Cree una Dynamic Table que actualice automáticamente los resultados de las consultas desde las tablas base mediante una actualización incremental o completa.
Notas importantes
Límites de uso de Dynamic Table: Dynamic Table support and limitations.
Hologres V3.1 y versiones posteriores requieren la nueva sintaxis para crear Dynamic Tables. Las operaciones ALTER siguen funcionando en las tablas creadas con la sintaxis de V3.0, pero no es posible crear tablas nuevas con ella. Para las tablas sin particiones, utilice syntax conversion command para convertir la sintaxis anterior a la nueva. En el caso de las tablas con particiones, vuelva a crearlas manualmente.
Al actualizar a Hologres V3.1 o versiones posteriores, debe volver a crear las Incremental Dynamic Tables existentes. Para ello, utilice syntax conversion command.
En Hologres V3.1 y versiones posteriores, el motor optimiza el proceso de actualización de forma adaptativa. Es normal que las operaciones de actualización presenten identificadores de consulta negativos.
Sintaxis
V3.1 y versiones posteriores (sintaxis nueva)
Las versiones V3.1 y posteriores solo admiten la sintaxis nueva.
Sintaxis para crear una Dynamic Table
Sintaxis para crear una Dynamic Table en V3.1 y versiones posteriores:
CREATE DYNAMIC TABLE [ IF NOT EXISTS ] [<schema_name>.]<table_name>
[ (<col_name> [, ...] ) ]
[LOGICAL PARTITION BY LIST(<partition_key>)]
WITH (
-- Dynamic Table properties
freshness = {'<num> {minutes | hours}' | 'upstream'}, -- Required
[auto_refresh_enable = {true | false},] -- Optional
[auto_refresh_mode = {'full' | 'incremental' | 'auto'},] -- Optional
[base_table_cdc_format = {'stream' | 'binlog'},] -- Optional
[auto_refresh_partition_active_time = '<num> {minutes | hours | days}',] -- Optional
[partition_key_time_format = {'YYYYMMDDHH24' | 'YYYY-MM-DD-HH24' | 'YYYY-MM-DD_HH24' | 'YYYYMMDD' | 'YYYY-MM-DD' | 'YYYYMM' | 'YYYY-MM' | 'YYYY'},] --Optional
[computing_resource = {'local' | 'serverless' | '<warehouse_name>'},] -- Optional. The warehouse_name value is supported only in Hologres V4.0.7 and later.
[refresh_guc_hg_experimental_serverless_computing_required_cores=xxx,] --Optional. Specifies the required computing cores for Serverless.
[refresh_guc_<guc_name> = '<guc_value>',] -- Optional
-- General properties
[orientation = {'column' | 'row' | 'row,column'},]
[table_group = '<tableGroupName>',]
[distribution_key = '<columnName>[,...]]',]
[clustering_key = '<columnName>[:asc] [,...]',]
[event_time_column = '<columnName> [,...]',]
[bitmap_columns = '<columnName> [,...]',]
[dictionary_encoding_columns = '<columnName> [,...]',]
[time_to_live_in_seconds = '<non_negative_literal>',]
[storage_mode = {'hot' | 'cold'},]
)
AS
<query>; -- Query definition.
Parámetros
Modo de actualización y recursos
|
Parámetro |
Descripción |
Obligatorio |
Predeterminado |
|
|
Actualidad objetivo de los datos, expresada en minutos u horas. El valor mínimo es 1 minuto. El motor programa las actualizaciones según la hora de la actualización anterior y este valor de
|
Sí |
Ninguna |
|
|
El modo de actualización. Valores válidos:
|
No |
auto |
|
|
Habilite o deshabilite la actualización automática. Valores válidos:
|
No |
true |
|
|
Define cómo se consumen los cambios de datos de la tabla base durante la actualización incremental.
Nota
|
No |
stream |
|
|
Recurso de cómputo para la actualización. Valores válidos:
|
No |
serverless |
|
|
Establezca los parámetros GUC para la actualización. Para consultar los parámetros GUC compatibles, consulte GUC parameters. |
No |
Ninguna |
Tablas con particiones
Tabla con particiones lógicas
|
Parámetro |
Descripción |
Obligatorio |
Predeterminado |
|
|
Crea una Dynamic Table con particiones lógicas. Requiere |
No |
Ninguna |
|
|
Alcance de la actualización para las particiones, expresado en minutos, horas o días. Hologres retrocede desde la hora actual y actualiza las particiones dentro de esta ventana. Las particiones activas son aquellas cuyo tiempo transcurrido desde el inicio (derivado del nombre de la partición) es menor que el valor de Nota
|
Sí |
El valor predeterminado es Esto proporciona un margen de 1 hora para compensar posibles retrasos de datos provenientes de la tabla base. Por ejemplo, con particiones diarias, el valor predeterminado es de 25 horas (1 día + 1 hora). |
|
|
Formato del nombre de la partición. Valores válidos:
|
Sí |
Ninguna |
Tablas con particiones físicas
|
Parámetro |
Descripción |
Obligatorio |
Predeterminado |
|
|
Crea una Dynamic Table con particiones físicas. Las Dynamic Tables con particiones físicas carecen de particionamiento dinámico y presentan limitaciones de uso. Se recomienda utilizar particiones lógicas. Para conocer las diferencias, consulte CREATE LOGICAL PARTITION TABLE. Importante
Hologres V3.1 y versiones posteriores no admiten la creación de una Dynamic Table como tabla con particiones físicas. |
No |
Ninguna |
Propiedades de la tabla
|
Parámetro |
Descripción |
Obligatorio |
Valor predeterminado |
|
|
Modo de actualización completa |
Modo de actualización incremental |
|||
|
|
Nombres de las columnas. Especifique los nombres, pero no los atributos ni los tipos de datos, ya que el motor los deduce automáticamente. Nota
Especificar los atributos y los tipos de datos de las columnas provoca inferencias incorrectas por parte del motor. |
No |
Nombre de la columna de la consulta |
Nombre de la columna de la consulta |
|
|
Formato de almacenamiento. |
No |
|
|
|
|
Table Group. De forma predeterminada, toma el valor de la base de datos actual. Para obtener más información, consulte Manage table groups and shards. |
No |
Nombre del Table Group predeterminado |
Nombre del Table Group predeterminado |
|
|
Clave de distribución. Para obtener más información, consulte Distribution key. |
No |
(ninguno) |
(ninguno) |
|
|
Clave de agrupación. Para obtener más información, consulte Clustering key. |
No |
Permitido, con un valor inferido de forma predeterminada. |
Permitido, con un valor inferido de forma predeterminada. |
|
|
Consulte Event time column (segment key). |
No |
(ninguno) |
(ninguno) |
|
|
Columnas de mapa de bits. Para obtener más información, consulte Bitmap index. |
No |
Campos de tipo TEXT |
Campos de tipo TEXT |
|
|
Consulte Dictionary encoding. |
No |
Campos de tipo TEXT |
Campos de tipo TEXT |
|
|
TTL de los datos. |
No |
Sin caducidad |
Sin caducidad |
|
|
Nivel de almacenamiento. Valores válidos:
Nota
Para obtener más detalles, consulte Set up storage tiering. |
No |
|
|
|
|
Habilita binlog para la Dynamic Table. Subscribe to Hologres Binlog. Nota
|
No |
|
|
|
|
El TTL de binlog. |
No |
|
|
Actualización en cascada
Hologres V5.0 y versiones posteriores admiten la actualización en cascada. Cuando las tablas base de una dynamic table incluyen otras dynamic tables, establezca su freshness en 'upstream' para que la tabla se actualice automáticamente después de que finalice la actualización de su dynamic table superior. Esto forma una cadena de actualización en cascada. Este enfoque es ideal para escenarios de almacenes de varias capas: defina un valor de actualidad explícito solo en la raíz de la cadena y configure cada capa inferior en 'upstream'. Así, los datos fluyen capa por capa sin necesidad de un intervalo de actualización para cada una ni de un programador externo que orqueste las dependencias.
Ejemplo
-- Root: refreshed on a fixed freshness.
CREATE DYNAMIC TABLE dwd_orders
WITH (
auto_refresh_mode = 'incremental',
freshness = '5 minutes'
)
AS SELECT order_id, user_id, ds, amount FROM ods_orders;
-- Second layer: triggered after dwd_orders is refreshed.
CREATE DYNAMIC TABLE dws_user_amount
WITH (
auto_refresh_mode = 'incremental',
freshness = 'upstream'
)
AS SELECT user_id, ds, SUM(amount) AS amt FROM dwd_orders GROUP BY user_id, ds;
-- Third layer: triggered after dws_user_amount is refreshed.
CREATE DYNAMIC TABLE ads_daily_amount
WITH (
auto_refresh_mode = 'incremental',
freshness = 'upstream'
)
AS SELECT ds, SUM(amt) AS amt FROM dws_user_amount GROUP BY ds;
Para supervisar una cadena en cascada, consulte hologres.hg_dynamic_table_refresh_history. Las actualizaciones activadas por una tabla superior se registran con el tipo de activación cascade.
SELECT dynamic_table_name, refresh_type, status, refresh_start
FROM hologres.hg_dynamic_table_refresh_history
WHERE schema_name = '<SCHEMA_NAME>'
ORDER BY refresh_start;
Comportamiento de activación
Las activaciones se propagan de un nivel a la vez: cuando una dynamic table superior termina de actualizarse, activa sus tablas inferiores directas, y cada una de ellas activa el siguiente nivel al finalizar. Una tabla superior nunca activa directamente a una tabla de segundo nivel descendiente. En una cadena de A a B y luego a C, la tabla C se activa por B, no por A.
Una tabla superior devuelve el control en cuanto finaliza su propia actualización, sin esperar a las actualizaciones de las tablas inferiores. Lo mismo aplica para una ejecución manual de
REFRESH DYNAMIC TABLE: el comando devuelve el control cuando se actualiza la tabla actual, y las actualizaciones de las tablas inferiores se ejecutan de forma asíncrona después. Para controlar si una actualización manual activa las tablas inferiores, utilice el parámetrocascading. Para obtener más información, consulte Refresh dynamic table.Cuando una dynamic table tiene varias dynamic tables superiores, la actualización exitosa de cualquiera de ellas activa una actualización de esta tabla, sin esperar a las demás tablas superiores. Como resultado, la tabla combina los datos más recientes de algunas tablas superiores con datos antiguos de otras. Este es el comportamiento esperado de la actualización en cascada. Si su lógica de negocio requiere que todos los datos de las tablas superiores estén alineados, no dependa de las activaciones en cascada. Actualice la tabla manualmente cuando todos los datos superiores estén listos.
Consulta
La consulta define los datos de la Dynamic Table. Las consultas y las tablas base compatibles varían según el modo de actualización. Para obtener más información, consulte Dynamic Table support and limitations.
V3.0 (sintaxis anterior)
Sintaxis para crear una Dynamic Table
CREATE DYNAMIC TABLE [IF NOT EXISTS] <schema.tablename>(
[col_name],
[col_name]
) [PARTITION BY LIST (col_name)]
WITH (
[refresh_mode='[full|incremental]',]
[auto_refresh_enable='[true|false',]
--Incremental refresh parameters:
[incremental_auto_refresh_schd_start_time='[immediate|<timestamptz>]',]
[incremental_auto_refresh_interval='[<num> {minute|minutes|hour|hours]',]
[incremental_guc_hg_computing_resource='[ local | serverless]',]
[incremental_guc_hg_experimental_serverless_computing_required_cores='<num>',]
--Full refresh parameters:
[full_auto_refresh_schd_start_time='[immediate|<timestamptz>]',]
[full_auto_refresh_interval='[<num> {minute|minutes|hour|hours]',]
[full_guc_hg_computing_resource='[ local | serverless]',]--hg_full_refresh_computing_resource defaults to serverless, can be set at the DB level, and is optional for users.
[full_guc_hg_experimental_serverless_computing_required_cores='<num>',]
--Shared parameters, GUCs are allowed:
[refresh_guc_<guc>='xxx]',]
-- General Dynamic Table properties:
[orientation = '[column]',]
[table_group = '[tableGroupName]',]
[distribution_key = 'columnName[,...]]',]
[clustering_key = '[columnName{:asc]} [,...]]',]
[event_time_column = '[columnName [,...]]',]
[bitmap_columns = '[columnName [,...]]',]
[dictionary_encoding_columns = '[columnName [,...]]',]
[time_to_live_in_seconds = '<non_negative_literal>',]
[storage_mode = '[hot | cold]']
)
AS
<query> --Query definition
Parámetros
Modo de actualización y recursos
|
Categoría |
Parámetro |
Descripción |
Obligatorio |
Predeterminado |
|
Parámetros compartidos de actualización |
|
Modo de actualización. Valores válidos: Si no se configura, no se ejecuta ninguna actualización. |
No |
(ninguno) |
|
|
Habilite o deshabilite la actualización automática. Valores válidos:
|
No |
false |
|
|
|
Establezca los parámetros GUC para la actualización. Para consultar la lista de GUC compatibles, consulte GUC parameters. Nota
Por ejemplo, para establecer el GUC de zona horaria, use |
No |
(ninguno) |
|
|
Actualización incremental |
|
Hora de inicio de la actualización incremental. Valores válidos:
|
No |
immediate |
|
|
Intervalo de actualización incremental, en minutos u horas.
|
No |
(ninguno) |
|
|
|
Recursos de cómputo para la actualización incremental. Valores válidos:
Nota
Para establecer los recursos de cómputo a nivel de base de datos, ejecute |
No |
local |
|
|
|
Núcleos de Serverless Computing para la actualización. Nota
Las cuotas de recursos de Serverless Computing varían según las especificaciones de la instancia. Para obtener más información, consulte Manage serverless computing resources. |
No |
(ninguno) |
|
|
Actualización completa |
|
Hora de inicio de la actualización completa. Valores válidos:
|
No |
immediate |
|
|
Intervalo de actualización completa, en minutos u horas.
|
No |
(ninguno) |
|
|
|
Recursos de cómputo para la actualización completa. Valores válidos:
Nota
Para establecer los recursos de cómputo a nivel de base de datos, ejecute |
No |
local |
|
|
|
Núcleos de Serverless Computing para la actualización. Nota
Las cuotas de recursos de Serverless Computing varían según las especificaciones de la instancia. Para obtener más información, consulte Manage serverless computing resources. |
No |
(ninguno) |
Propiedades de la tabla
|
Parámetro |
Descripción |
Obligatorio |
Predeterminado |
|
|
full |
incremental |
|||
|
|
Nombres de columna. Especifique los nombres, pero no los atributos ni los tipos de datos, ya que el motor los deduce automáticamente. Nota
Especificar atributos y tipos de datos de columna puede provocar inferencias incorrectas por parte del motor. |
No |
Nombre de columna de la consulta |
Nombre de columna de la consulta |
|
|
Formato de almacenamiento de la Dynamic Table. El valor |
No |
|
|
|
|
Table Group. De forma predeterminada, usa el grupo de la base de datos actual. Para obtener más información, consulte Manage table groups and shards. |
No |
Nombre del Table Group predeterminado |
Nombre del Table Group predeterminado |
|
|
Clave de distribución. Para obtener más información, consulte Distribution key. |
No |
(ninguna) |
(ninguna) |
|
|
Clave de agrupamiento. Para obtener más información, consulte Clustering key. |
No |
Permitida, con un valor inferido de forma predeterminada. |
Permitida, con un valor inferido de forma predeterminada. |
|
|
Clave de segmento. Para obtener más información, consulte Event time column (segment key). |
No |
(ninguna) |
(ninguna) |
|
|
Columnas de mapa de bits. Para obtener más información, consulte Bitmap index. |
No |
Campos de tipo TEXT |
Campos de tipo TEXT |
|
|
Consulte Dictionary encoding. |
No |
Campos de tipo TEXT |
Campos de tipo TEXT |
|
|
TTL de los datos. |
No |
Sin caducidad |
Sin caducidad |
|
|
Nivel de almacenamiento. Valores válidos:
Nota
Consulte Set up storage tiering. |
No |
|
|
|
|
Crea una Dynamic Table particionada. Las particiones pueden usar distintos modos de actualización según los requisitos de frescura de los datos. |
No |
Tabla sin particiones |
Tabla sin particiones |
Consulta
La consulta que genera los datos de la Dynamic Table. Las consultas y los tipos de tabla base compatibles varían según el modo de actualización. Dynamic Table support and limitations.
Actualización incremental
La actualización incremental detecta los cambios en la tabla base y escribe únicamente el delta en la Dynamic Table. Este método es ideal para consultas casi en tiempo real (a nivel de minutos).
-
Limitaciones de la tabla base:
En la versión V3.1 se usa de forma predeterminada el modo
stream. Si habilitó el binlog de su tabla base en la V3.0, deshabilítelo para evitar costos adicionales de almacenamiento.En la V3.0, debe habilitar el binlog para la tabla base, excepto cuando se trata de una tabla de dimensiones involucrada en un join. Habilitar el binlog en una tabla base genera cierta sobrecarga de almacenamiento. Consulte el uso de almacenamiento del binlog en View table storage details.
En el modo de actualización incremental, Hologres genera una tabla de estado en segundo plano para registrar los resultados intermedios de agregación (consulte Dynamic tables para más detalles). Esta tabla también consume espacio para almacenar el estado. Para revisar el uso de almacenamiento, consulte View dynamic table schema and lineage.
Consultas y operadores compatibles con la actualización incremental: Dynamic Table support and limitations.
Cuando ejecuta una actualización incremental por primera vez, el sistema carga todos los datos e inicializa la tabla de estado que se usa para el seguimiento. Como se procesan todos los datos históricos al mismo tiempo y se inicializan las estructuras de estado, el consumo de memoria y de recursos de cómputo es mucho mayor que en los ciclos incrementales posteriores. Si el volumen de datos de la tabla base es grande o los recursos son insuficientes, podría producirse un error de falta de memoria (OOM).
Para evitar cuellos de botella en los recursos, evalúe el volumen de datos de la tabla base antes de la primera ejecución y utilice recursos de Serverless Computing para ejecutarla. Para obtener más información, consulte @xref node="5933653" Use Serverless Computing for data reads and writes @/xref .
Joins entre flujos
Los JOIN entre flujos tienen la misma semántica que las consultas OLAP. Utilizan HASH JOIN y admiten INNER JOIN, así como LEFT/RIGHT/FULL OUTER JOIN.
V3.1
A partir de Hologres V3.1, el GUC para JOIN entre flujos está habilitado de forma predeterminada.
Ejemplo:
CREATE TABLE users (
user_id INT,
user_name TEXT,
PRIMARY KEY (user_id)
);
INSERT INTO users VALUES(1, 'hologres');
CREATE TABLE orders (
order_id INT,
user_id INT,
PRIMARY KEY (order_id)
);
INSERT INTO orders VALUES(1, 1);
CREATE DYNAMIC TABLE dt WITH (
auto_refresh_mode = 'incremental',
freshness='10 minutes'
)
AS
SELECT order_id, orders.user_id, user_name
FROM orders LEFT JOIN users ON orders.user_id = users.user_id;
-- After refresh, one joined record is visible
REFRESH TABLE dt;
SELECT * FROM dt;
order_id | user_id | user_name
----------+---------+-----------
1 | 1 | hologres
(1 row)
UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);
-- After refresh, two joined records are visible. Dimension table updates affect all data and can correct previously joined records.
REFRESH TABLE dt;
SELECT * FROM dt;
Resultado:
order_id | user_id | user_name
----------+---------+---------------
1 | 1 | dynamic table
4 | 1 | dynamic table
(2 rows)
V3.0
Los JOIN entre flujos son compatibles a partir de la V3.0.26. Para habilitar esta función, actualice su instancia y configure el GUC:
-- Enable at session level
SET hg_experimental_incremental_dynamic_table_enable_hash_join TO ON;
-- Enable at DB level (takes effect for new connections)
ALTER database <db_name> SET hg_experimental_incremental_dynamic_table_enable_hash_join TO ON;
Ejemplo:
CREATE TABLE users (
user_id INT,
user_name TEXT,
PRIMARY KEY (user_id)
) WITH (binlog_level = 'replica');
INSERT INTO users VALUES(1, 'hologres');
CREATE TABLE orders (
order_id INT,
user_id INT,
PRIMARY KEY (order_id)
) WITH (binlog_level = 'replica');
INSERT INTO orders VALUES(1, 1);
CREATE DYNAMIC TABLE dt WITH (refresh_mode = 'incremental')
AS
SELECT order_id, orders.user_id, user_name
FROM orders LEFT JOIN users ON orders.user_id = users.user_id;
-- After refresh, one joined record is visible
REFRESH TABLE dt;
SELECT * FROM dt;
order_id | user_id | user_name
----------+---------+-----------
1 | 1 | hologres
(1 row)
UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);
-- After refresh, two joined records are visible. Dimension table updates affect all data and can correct previously joined records.
REFRESH TABLE dt;
SELECT * FROM dt;
Resultado:
order_id | user_id | user_name
----------+---------+---------------
1 | 1 | dynamic table
4 | 1 | dynamic table
(2 rows)
Joins con tablas de dimensiones
Cada registro del flujo se une con la instantánea más reciente de la tabla de dimensiones al momento del procesamiento. Los cambios posteriores al JOIN en la tabla de dimensiones no afectan los datos que ya se procesaron.
El comportamiento del JOIN con una tabla de dimensiones no depende de su tamaño, sino de la instrucción JOIN.
V3.1
CREATE TABLE users (
user_id INT,
user_name TEXT,
PRIMARY KEY (user_id)
);
INSERT INTO users VALUES(1, 'hologres');
CREATE TABLE orders (
order_id INT,
user_id INT,
PRIMARY KEY (order_id)
) WITH (binlog_level = 'replica');
INSERT INTO orders VALUES(1, 1);
CREATE DYNAMIC TABLE dt_join_2 WITH (
auto_refresh_mode = 'incremental',
freshness='10 minutes')
AS
SELECT order_id, orders.user_id, user_name
-- FOR SYSTEM_TIME AS OF PROCTIME() identifies 'users' as a dimension table
FROM orders LEFT JOIN users FOR SYSTEM_TIME AS OF PROCTIME()
ON orders.user_id = users.user_id;
-- After refresh, one joined record is visible
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;
order_id | user_id | user_name
----------+---------+-----------
1 | 1 | hologres
(1 row)
UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);
-- After refresh, two joined records are visible. Dimension table updates only affect new data and cannot correct previously joined data.
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;
Resultado:
order_id | user_id | user_name
----------+---------+---------------
1 | 1 | hologres
4 | 1 | dynamic table
(2 rows)
V3.0
CREATE TABLE users (
user_id INT,
user_name TEXT,
PRIMARY KEY (user_id)
);
INSERT INTO users VALUES(1, 'hologres');
CREATE TABLE orders (
order_id INT,
user_id INT,
PRIMARY KEY (order_id)
) WITH (binlog_level = 'replica');
INSERT INTO orders VALUES(1, 1);
CREATE DYNAMIC TABLE dt_join_2 WITH (refresh_mode = 'incremental')
AS
SELECT order_id, orders.user_id, user_name
-- FOR SYSTEM_TIME AS OF PROCTIME() identifies 'users' as a dimension table
FROM orders LEFT JOIN users FOR SYSTEM_TIME AS OF PROCTIME()
ON orders.user_id = users.user_id;
-- After refresh, one joined record is visible
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;
order_id | user_id | user_name
----------+---------+-----------
1 | 1 | hologres
(1 row)
UPDATE users SET user_name = 'dynamic table' WHERE user_id = 1;
INSERT INTO orders VALUES(4, 1);
-- After refresh, two joined records are visible. Dimension table updates only affect new data and cannot correct previously joined data.
REFRESH TABLE dt_join_2;
SELECT * FROM dt_join_2;
Resultado:
order_id | user_id | user_name
----------+---------+---------------
1 | 1 | hologres
4 | 1 | dynamic table
(2 rows)
Limitaciones
Una columna obtenida de un join con una tabla de dimensiones es no determinista: su valor depende tanto de la fila actual de la tabla de hechos como del contenido de la tabla de dimensiones al momento del procesamiento. En este sentido, se comporta igual que las funciones no deterministas NOW() y RAND(). Se recomienda utilizar este tipo de columnas únicamente en la lista de proyección del SELECT. Usarlas en otras partes puede provocar errores de actualización o resultados inesperados.
|
Ubicación de uso |
Permitido |
|
Lista de proyección del SELECT |
Sí |
|
Argumento de una función de agregación, como |
Sí, aunque no se recomienda. Cuando una retracción desencadena un nuevo cálculo, el valor de la tabla de dimensiones podría haber cambiado, lo que genera resultados inesperados. |
|
Clave de GROUP BY |
No |
|
Predicado de WHERE |
No |
|
Condición ON de un JOIN posterior |
No |
|
Cláusula PARTITION BY de una función de ventana |
No |
Si su lógica de negocio requiere agrupar o filtrar por una columna de la tabla de dimensiones, utilice un stream-stream join. De esta manera, cualquier cambio en la tabla de dimensiones desencadenará una retracción y un nuevo cálculo de los datos históricos, lo que mantiene la exactitud de los resultados.
Sin embargo, un join entre flujos debe mantener el estado del JOIN, por lo que consume más recursos cuando la tabla de dimensiones es grande. Además, los cambios masivos en dicha tabla pueden desencadenar cálculos extensos en las etapas posteriores.
Consumo incremental de tablas lake de Paimon
La actualización incremental admite el consumo de tablas Paimon para escenarios de lakehouse.
Las Dynamic Tables externas admiten lecturas incrementales y escritura de retorno, lo que reduce el costo de procesamiento y la latencia de las consultas. External Dynamic Table introduction.
Consumo híbrido
Las Dynamic Tables incrementales admiten un modelo híbrido: primero se cargan todos los datos existentes de la tabla base y después se aplica un procesamiento incremental continuo.
V3.1
La V3.1 habilita el modelo de actualización híbrida de forma predeterminada. Ejemplo:
--Prepare the base table and insert data
CREATE TABLE base_sales(
day TEXT NOT NULL,
hour INT,
user_id BIGINT,
ts TIMESTAMPTZ,
amount FLOAT,
pk text NOT NULL PRIMARY KEY
);
-- Import data into the base table
INSERT INTO base_sales values ('2024-08-29',1,222222,'2024-08-29 16:41:19.141528+08',5,'ddd');
-- Import more data
INSERT INTO base_sales VALUES ('2024-08-29',2,3333,'2024-08-29 17:44:19.141528+08',100,'aaaaa');
-- Create an incremental Dynamic Table
CREATE DYNAMIC TABLE sales_incremental
WITH (
auto_refresh_mode='incremental',
freshness='10 minutes'
)
AS
SELECT day, hour, SUM(amount), COUNT(1)
FROM base_sales
GROUP BY day, hour;
Compruebe la consistencia de los datos:
-
Consulte la tabla base
SELECT day, hour, SUM(amount), COUNT(1) FROM base_sales GROUP BY day, hour;Resultado:
day hour sum count 2024-08-29 2 100 1 2024-08-29 1 5 1 -
Consulte la Dynamic Table
SELECT * FROM sales_incremental;Resultado:
day hour sum count 2024-08-29 1 5 1 2024-08-29 2 100 1
V3.0
En la V3.0, para usar el consumo híbrido, habilite manualmente el GUC incremental_guc_hg_experimental_enable_hybrid_incremental_mode. Ejemplo:
--Prepare the base table, enable Binlog, and insert data
CREATE TABLE base_sales(
day TEXT NOT NULL,
hour INT,
user_id BIGINT,
ts TIMESTAMPTZ,
amount FLOAT,
pk text NOT NULL PRIMARY KEY
);
-- Import data into the base table
INSERT INTO base_sales values ('2024-08-29',1,222222,'2024-08-29 16:41:19.141528+08',5,'ddd');
-- Enable Binlog for the base table
ALTER TABLE base_sales SET (binlog_level = replica);
-- Import incremental data into the base table
INSERT INTO base_sales VALUES ('2024-08-29',2,3333,'2024-08-29 17:44:19.141528+08',100,'aaaaa');
-- Create an auto-refreshing incremental Dynamic Table and enable the GUC for hybrid consumption
CREATE DYNAMIC TABLE sales_incremental
WITH (
refresh_mode='incremental',
incremental_auto_refresh_schd_start_time = 'immediate',
incremental_auto_refresh_interval = '3 minutes',
incremental_guc_hg_experimental_enable_hybrid_incremental_mode= 'true'
)
AS
SELECT day, hour, SUM(amount), COUNT(1)
FROM base_sales
GROUP BY day, hour;
Compruebe la consistencia de los datos:
-
Consulte la tabla base
SELECT day, hour, SUM(amount), COUNT(1) FROM base_sales GROUP BY day, hour;Resultado:
day hour sum count 2024-08-29 2 100 1 2024-08-29 1 5 1 -
Consulte la Dynamic Table
SELECT * FROM sales_incremental;Resultado:
day hour sum count 2024-08-29 1 5 1 2024-08-29 2 100 1
Actualización completa
La actualización completa reescribe todo el conjunto de datos a partir de la consulta. En comparación con la actualización incremental:
Admite más tipos de tablas base.
Es compatible con una mayor variedad de tipos de consulta y operadores.
Este modo consume más recursos. Resulta más indicado para reportes periódicos y recargas de datos históricos.
Para obtener más información, consulte Full refresh.
Ejemplos
V3.1
Ejemplo 1: Crear una Dynamic Table incremental estándar
Antes de continuar, importe el conjunto de datos público tpch_10g a Hologres siguiendo la guía de Import public datasets with a few clicks.
Antes de crear una Dynamic Table incremental, habilite el binlog para la tabla base (no es necesario en las tablas de dimensiones).
-- Create an Incremental Dynamic Table that refreshes every 3 minutes.
CREATE DYNAMIC TABLE public.tpch_q1_incremental
WITH (
auto_refresh_mode='incremental',
freshness='3 minutes'
) AS SELECT
l_returnflag,
l_linestatus,
COUNT(*) AS count_order
FROM
hologres_dataset_tpch_10g.lineitem
WHERE
l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
l_returnflag,
l_linestatus;
Ejemplo 2: Crear una Dynamic Table incremental a partir de joins entre flujos
Antes de continuar, importe el conjunto de datos público tpch_10g a Hologres siguiendo la guía de Import public datasets with a few clicks.
Antes de crear una Dynamic Table incremental, habilite el binlog para la tabla base (no es necesario en la tabla de dimensiones).
-- Create an Incremental Dynamic Table from stream-stream joins.
CREATE DYNAMIC TABLE dt_join
WITH (
auto_refresh_mode='incremental',
freshness='30 minutes'
)
AS
SELECT
l_shipmode,
SUM(CASE
WHEN o_orderpriority = '1-URGENT'
OR o_orderpriority = '2-HIGH'
THEN 1
ELSE 0
END) AS high_line_count,
SUM(CASE
WHEN o_orderpriority <> '1-URGENT'
AND o_orderpriority <> '2-HIGH'
THEN 1
ELSE 0
END) AS low_line_count
FROM
hologres_dataset_tpch_10g.orders,
hologres_dataset_tpch_10g.lineitem
WHERE
o_orderkey = l_orderkey
AND l_shipmode IN ('FOB', 'AIR')
AND l_commitdate < l_receiptdate
AND l_shipdate < l_commitdate
AND l_receiptdate >= DATE '1997-01-01'
AND l_receiptdate < DATE '1997-01-01' + INTERVAL '1' YEAR
GROUP BY
l_shipmode;
Ejemplo 3: Crear una Dynamic Table con actualización automática
Establezca el modo de actualización en automático. El motor prioriza la actualización incremental y recurre a la completa si la primera no es compatible.
Antes de continuar, importe el conjunto de datos público tpch_10g a Hologres siguiendo la guía de Import public datasets with a few clicks.
-- Create an Auto-refresh Dynamic Table that intelligent decides the refresh mode. In this example, incremental refresh is the result.
CREATE DYNAMIC TABLE thch_q6_auto
WITH (
auto_refresh_mode='auto',
freshness='1 hours'
)
AS
SELECT
SUM(l_extendedprice * l_discount) AS revenue
FROM
hologres_dataset_tpch_100g.lineitem
WHERE
l_shipdate >= DATE '1996-01-01'
AND l_shipdate < DATE '1996-01-01' + INTERVAL '1' YEAR
AND l_discount BETWEEN 0.02 - 0.01 AND 0.02 + 0.01
AND l_quantity < 24;
Ejemplo 4: Crear una Dynamic Table con particiones lógicas
En un panel de transacciones en tiempo real, suele ser necesario consultar los datos actuales casi en tiempo real y corregir los datos históricos. Esto requiere una solución que integre el análisis en tiempo real y por lotes (Business and data cognition). Para este escenario se utilizan las particiones lógicas de Dynamic Table. El enfoque es el siguiente:
La tabla base está particionada por día. Flink escribe la partición más reciente en tiempo real o casi en tiempo real, mientras que las particiones históricas se escriben desde MaxCompute.
La Dynamic Table se crea como una tabla con particiones lógicas. Las dos particiones más recientes están activas y se actualizan de forma incremental para el análisis de datos casi en tiempo real.
Las particiones históricas están inactivas y usan actualización completa. Si las particiones históricas de la tabla base se corrigieron o rellenaron, se pueden actualizar mediante una actualización completa.
Este ejemplo utiliza un conjunto de datos público de GitHub.
-
Prepare la tabla base.
Use Flink para escribir los datos más recientes en la tabla base. Para conocer los pasos detallados, consulte Unified batch and real-time analytics on GitHub events.
DROP TABLE IF EXISTS gh_realtime_data; BEGIN; CREATE TABLE gh_realtime_data ( id BIGINT, actor_id BIGINT, actor_login TEXT, repo_id BIGINT, repo_name TEXT, org_id BIGINT, org_login TEXT, type TEXT, created_at timestamp with time zone NOT NULL, action TEXT, iss_or_pr_id BIGINT, number BIGINT, comment_id BIGINT, commit_id TEXT, member_id BIGINT, rev_or_push_or_rel_id BIGINT, ref TEXT, ref_type TEXT, state TEXT, author_association TEXT, language TEXT, merged BOOLEAN, merged_at TIMESTAMP WITH TIME ZONE, additions BIGINT, deletions BIGINT, changed_files BIGINT, push_size BIGINT, push_distinct_size BIGINT, hr TEXT, month TEXT, year TEXT, ds TEXT, PRIMARY KEY (id,ds) ) PARTITION BY LIST (ds); CALL set_table_property('public.gh_realtime_data', 'distribution_key', 'id'); CALL set_table_property('public.gh_realtime_data', 'event_time_column', 'created_at'); CALL set_table_property('public.gh_realtime_data', 'clustering_key', 'created_at'); COMMENT ON COLUMN public.gh_realtime_data.id IS 'Event ID'; COMMENT ON COLUMN public.gh_realtime_data.actor_id IS 'Event actor ID'; COMMENT ON COLUMN public.gh_realtime_data.actor_login IS 'Event actor login name'; COMMENT ON COLUMN public.gh_realtime_data.repo_id IS 'Repo ID'; COMMENT ON COLUMN public.gh_realtime_data.repo_name IS 'Repo name'; COMMENT ON COLUMN public.gh_realtime_data.org_id IS 'Repo organization ID'; COMMENT ON COLUMN public.gh_realtime_data.org_login IS 'Repo organization name'; COMMENT ON COLUMN public.gh_realtime_data.type IS 'Event type'; COMMENT ON COLUMN public.gh_realtime_data.created_at IS 'Event time'; COMMENT ON COLUMN public.gh_realtime_data.action IS 'Event action'; COMMENT ON COLUMN public.gh_realtime_data.iss_or_pr_id IS 'Issue/pull_request ID'; COMMENT ON COLUMN public.gh_realtime_data.number IS 'Issue/pull_request number'; COMMENT ON COLUMN public.gh_realtime_data.comment_id IS 'Comment ID'; COMMENT ON COLUMN public.gh_realtime_data.commit_id IS 'Commit ID'; COMMENT ON COLUMN public.gh_realtime_data.member_id IS 'Member ID'; COMMENT ON COLUMN public.gh_realtime_data.rev_or_push_or_rel_id IS 'Review/push/release ID'; COMMENT ON COLUMN public.gh_realtime_data.ref IS 'Name of created/deleted resource'; COMMENT ON COLUMN public.gh_realtime_data.ref_type IS 'Type of created/deleted resource'; COMMENT ON COLUMN public.gh_realtime_data.state IS 'State of issue/pull_request/pull_request_review'; COMMENT ON COLUMN public.gh_realtime_data.author_association IS 'Relationship between actor and repo'; COMMENT ON COLUMN public.gh_realtime_data.language IS 'Programming language'; COMMENT ON COLUMN public.gh_realtime_data.merged IS 'Whether merged'; COMMENT ON COLUMN public.gh_realtime_data.merged_at IS 'Merge time'; COMMENT ON COLUMN public.gh_realtime_data.additions IS 'Number of added lines'; COMMENT ON COLUMN public.gh_realtime_data.deletions IS 'Number of deleted lines'; COMMENT ON COLUMN public.gh_realtime_data.changed_files IS 'Number of changed files in pull request'; COMMENT ON COLUMN public.gh_realtime_data.push_size IS 'Number of pushes'; COMMENT ON COLUMN public.gh_realtime_data.push_distinct_size IS 'Number of distinct pushes'; COMMENT ON COLUMN public.gh_realtime_data.hr IS 'Hour of event, e.g., 00 for 00:23'; COMMENT ON COLUMN public.gh_realtime_data.month IS 'Month of event, e.g., 2015-10 for Oct 2015'; COMMENT ON COLUMN public.gh_realtime_data.year IS 'Year of event, e.g., 2015'; COMMENT ON COLUMN public.gh_realtime_data.ds IS 'Date of event, ds=yyyy-mm-dd'; COMMIT; -
Cree una Dynamic Table con particiones lógicas.
CREATE DYNAMIC TABLE ads_dt_github_event LOGICAL PARTITION BY LIST(ds) WITH ( -- Dynamic table properties freshness = '5 minutes', auto_refresh_mode = 'auto', auto_refresh_partition_active_time = '2 days' , partition_key_time_format = 'YYYY-MM-DD' ) AS SELECT repo_name, COUNT(*) AS events, ds FROM gh_realtime_data GROUP BY repo_name,ds -
Consulte la Dynamic Table.
SELECT * FROM ads_dt_github_event ; -
Rellene una partición histórica.
Si los datos históricos de la tabla base cambian (por ejemplo, los datos del '2025-04-01') y necesita actualizar la Dynamic Table, configure la partición histórica en modo de actualización completa y active la actualización. Se recomienda usar recursos de Serverless Computing.
REFRESH OVERWRITE DYNAMIC TABLE ads_dt_github_event PARTITION (ds = '2025-04-01') WITH ( refresh_mode = 'full' );
Ejemplo 5: Calcular UV con una Dynamic Table incremental
A partir de Hologres V3.1, una Dynamic Table incremental es compatible con la función RB_BUILD_AGG para cálculos como el número de UV. En comparación con la preagregación, esto ofrece lo siguiente:
Mayor velocidad: solo procesa los datos incrementales.
Menor costo: reduce el volumen de datos y el uso de recursos, lo que permite ejecutar cálculos sobre periodos más largos.
Ejemplo:
-
Prepare una tabla de detalles de usuarios.
BEGIN; CREATE TABLE IF NOT EXISTS ods_app_detail ( uid INT, country TEXT, prov TEXT, city TEXT, channel TEXT, operator TEXT, brand TEXT, ip TEXT, click_time TEXT, year TEXT, month TEXT, day TEXT, ymd TEXT NOT NULL ); CALL set_table_property('ods_app_detail', 'orientation', 'column'); CALL set_table_property('ods_app_detail', 'bitmap_columns', 'country,prov,city,channel,operator,brand,ip,click_time, year, month, day, ymd'); -- Set distribution_key based on query needs for optimal sharding effect. CALL set_table_property('ods_app_detail', 'distribution_key', 'uid'); -- For a field with full date-time used in WHERE filters, setting it as clustering_key and event_time_column is recommended. CALL set_table_property('ods_app_detail', 'clustering_key', 'ymd'); CALL set_table_property('ods_app_detail', 'event_time_column', 'ymd'); COMMIT; -
Calcule los UV mediante una Dynamic Table incremental.
CREATE DYNAMIC TABLE ads_uv_dt WITH ( freshness = '5 minutes', auto_refresh_mode = 'incremental') AS SELECT RB_BUILD_AGG(uid), country, prov, city, ymd, COUNT(1) FROM ods_app_detail WHERE ymd >= '20231201' AND ymd <='20240502' GROUP BY country,prov,city,ymd; -
Consulte los UV de un día específico.
SELECT RB_CARDINALITY(RB_OR_AGG(rb_uid)) AS uv, country, prov, city, SUM(pv) AS pv FROM ads_uv_dt WHERE ymd = '20240329' GROUP BY country,prov,city;
V3.0
Ejemplo 1: Crear una tabla dinámica de actualización completa con inicio automático
Antes de continuar, importe el conjunto de datos público tpch_10g a Hologres. Siga la guía disponible en Import public datasets with a few clicks.
--Create "test" Schema
CREATE SCHEMA test;
--Create a single-table full refresh dynamic table, starting immediately and refreshing every hour.
CREATE DYNAMIC TABLE test.thch_q1_full
WITH (
refresh_mode='full',
auto_refresh_enable='true',
full_auto_refresh_interval='1 hours',
full_guc_hg_computing_resource='serverless',
full_guc_hg_experimental_serverless_computing_required_cores='32'
)
AS
SELECT
l_returnflag,
l_linestatus,
SUM(l_quantity) AS sum_qty,
SUM(l_extendedprice) AS sum_base_price,
SUM(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
SUM(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,
AVG(l_quantity) AS avg_qty,
AVG(l_extendedprice) AS avg_price,
AVG(l_discount) AS avg_disc,
COUNT(*) AS count_order
FROM
hologres_dataset_tpch_10g.lineitem
WHERE
l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
l_returnflag,
l_linestatus;
Ejemplo 2: Crear una tabla dinámica incremental con hora de inicio
Antes de continuar, importe el conjunto de datos público tpch_10g a Hologres. Siga la guía disponible en Import public datasets with a few clicks.
A continuación se muestra un ejemplo:
Antes de crear una Dynamic Table incremental, debe habilitar Binlog para la tabla base. Este paso no es obligatorio para las tablas de dimensiones.
--Enable binlog for the base table:
BEGIN;
CALL set_table_property('hologres_dataset_tpch_10g.lineitem', 'binlog.level', 'replica');
COMMIT;
--Create a single-table incremental refresh dynamic table, specifying a start time and a 3-minute refresh interval.
CREATE DYNAMIC TABLE public.tpch_q1_incremental
WITH (
refresh_mode='incremental',
auto_refresh_enable='true',
incremental_auto_refresh_schd_start_time='2024-09-15 23:50:0',
incremental_auto_refresh_interval='3 minutes',
incremental_guc_hg_computing_resource='serverless',
incremental_guc_hg_experimental_serverless_computing_required_cores='30'
) AS SELECT
l_returnflag,
l_linestatus,
COUNT(*) AS count_order
FROM
hologres_dataset_tpch_10g.lineitem
WHERE
l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
l_returnflag,
l_linestatus
;
Ejemplo 3: Crear una tabla dinámica de actualización completa con múltiples uniones
--Create a dynamic table with a multi-table join query, using full refresh mode every 3 hours.
CREATE DYNAMIC TABLE dt_q_full
WITH (
refresh_mode='full',
auto_refresh_enable='true',
full_auto_refresh_schd_start_time='immediate',
full_auto_refresh_interval='3 hours',
full_guc_hg_computing_resource='serverless',
full_guc_hg_experimental_serverless_computing_required_cores='64'
)
AS
SELECT
o_orderpriority,
COUNT(*) AS order_count
FROM
hologres_dataset_tpch_10g.orders
WHERE
o_orderdate >= DATE '1996-07-01'
AND o_orderdate < DATE '1996-07-01' + INTERVAL '3' MONTH
AND EXISTS (
SELECT
*
FROM
hologres_dataset_tpch_10g.lineitem
WHERE
l_orderkey = o_orderkey
AND l_commitdate < l_receiptdate
)
GROUP BY
o_orderpriority;
Ejemplo 4: Crear una tabla dinámica incremental con unión de dimensiones
A continuación se muestra un ejemplo:
Antes de crear una Dynamic Table incremental, debe habilitar Binlog para la tabla base. Este paso no es obligatorio para las tablas de dimensiones.
La semántica de un JOIN con una tabla de dimensiones indica que cada registro se une únicamente con la versión más reciente de los datos de dicha tabla en ese momento. Es decir, el JOIN ocurre en el tiempo de procesamiento. Si los datos de la tabla de dimensiones cambian después del JOIN (ya sea por inserción, actualización o eliminación), los datos ya unidos no se actualizan. Ejemplo de SQL:
--Detail table
BEGIN;
CREATE TABLE public.sale_detail(
app_id TEXT,
uid TEXT,
product TEXT,
gmv BIGINT,
order_time TIMESTAMPTZ
);
--Enable binlog for the base table; dimension tables do not require it.
CALL set_table_property('public.sale_detail', 'binlog.level', 'replica');
COMMIT;
--Property table
CREATE TABLE public.user_info(
uid TEXT,
province TEXT,
city TEXT
);
CREATE DYNAMIC TABLE public.dt_sales_incremental
WITH (
refresh_mode='incremental',
auto_refresh_enable='true',
incremental_auto_refresh_schd_start_time='2024-09-15 00:00:00',
incremental_auto_refresh_interval='5 minutes',
incremental_guc_hg_computing_resource='serverless',
incremental_guc_hg_experimental_serverless_computing_required_cores='128')
AS
SELECT
sale_detail.app_id,
sale_detail.uid,
product,
SUM(sale_detail.gmv) AS sum_gmv,
sale_detail.order_time,
user_info.province,
user_info.city
FROM public.sale_detail
INNER JOIN public.user_info FOR SYSTEM_TIME AS OF PROCTIME()
ON sale_detail.uid =user_info.uid
GROUP BY sale_detail.app_id,sale_detail.uid,sale_detail.product,sale_detail.order_time,user_info.province,user_info.city;
Ejemplo 5: Crear una tabla dinámica particionada
En un panel de transacciones en tiempo real, suele ser necesario consultar los datos actuales casi en tiempo real y corregir los datos históricos. Esto se logra al combinar la actualización incremental y completa de Dynamic Table. El enfoque es el siguiente:
Cree una tabla base particionada donde la partición más reciente reciba escrituras en tiempo real o casi en tiempo real, y las particiones históricas se corrijan de manera ocasional.
Cree una
Dynamic Tablecomo tabla principal particionada. Use la actualización incremental para la partición más reciente y así cubrir las necesidades de análisis casi en tiempo real.Cambie las particiones históricas al modo de actualización completa. Si las particiones históricas de la tabla de origen se corrigieron, también puede rellenar las particiones de la
Dynamic Tablemediante una actualización completa. Se recomienda usar recursos serverless para acelerar el proceso.
Ejemplo:
-
Prepare la tabla base y los datos.
La tabla base es una tabla particionada cuya partición más reciente recibe datos en tiempo real.
-- Create a partitioned source table CREATE TABLE base_sales( uid INT, opreate_time TIMESTAMPTZ, amount FLOAT, tt TEXT NOT NULL, ds TEXT, PRIMARY KEY(ds) ) PARTITION BY LIST (ds) ; --Historical partition CREATE TABLE base_sales_20240615 PARTITION OF base_sales FOR VALUES IN ('20240615'); INSERT INTO base_sales_20240615 VALUES (2,'2024-06-15 16:18:25.387466+08','111','2','20240615'); --Latest partition, typically for real-time writes CREATE TABLE base_sales_20240616 PARTITION OF base_sales FOR VALUES IN ('20240616'); INSERT INTO base_sales_20240616 VALUES (1,'2024-06-16 16:08:25.387466+08','2','1','20240616'); -
Cree la tabla principal de
Dynamic Tableparticionada. Defina únicamente la consulta, sin especificar un modo de actualización.--Create extension CREATE EXTENSION roaringbitmap; CREATE DYNAMIC TABLE partition_dt_base_sales PARTITION BY LIST (ds) as SELECT public.RB_BUILD_AGG(uid), opreate_time, amount, tt, ds, COUNT(1) FROM base_sales GROUP BY opreate_time ,amount,tt,ds; -
Cree las subtablas y establezca sus modos de actualización.
Puede crear las subparticiones de
Dynamic Tablede forma manual o dinámica mediante DataWorks. Configure la partición más reciente con actualización incremental y las particiones históricas con actualización completa.-- Enable Binlog for the base table ALTER TABLE base_sales SET (binlog_level = replica); -- Assume the historical Dynamic Table sub-partition is as follows: CREATE DYNAMIC TABLE partition_dt_base_sales_20240615 PARTITION OF partition_dt_base_sales FOR VALUES IN ('20240615') WITH ( refresh_mode='incremental', auto_refresh_enable='true', incremental_auto_refresh_schd_start_time='immediate', incremental_auto_refresh_interval='30 minutes' ); -- Create a new Dynamic Table sub-partition, set its refresh mode to incremental, start immediately, refresh every 30 minutes, and use instance resources. CREATE DYNAMIC TABLE partition_dt_base_sales_20240616 PARTITION OF partition_dt_base_sales FOR VALUES IN ('20240616') WITH ( refresh_mode='incremental', auto_refresh_enable='true', incremental_auto_refresh_schd_start_time='immediate', incremental_auto_refresh_interval='30 minutes' ); --Switch the historical partition to full refresh mode ALTER DYNAMIC TABLE partition_dt_base_sales_20240615 SET (refresh_mode = 'full'); --If historical partition data needs correction, execute a refresh, preferably with serverless. SET hg_computing_resource = 'serverless'; REFRESH DYNAMIC TABLE partition_dt_base_sales_20240615;
Convertir la sintaxis heredada a la nueva sintaxis
Hologres V3.1 modificó la sintaxis para crear una Dynamic Table. Después de actualizar desde la V3.0, vuelva a crear las Dynamic Tables con la nueva sintaxis. Una herramienta de conversión simplifica este proceso.
Escenarios
Las Dynamic Tables incrementales deben volver a crearse con la nueva sintaxis.
Se detectaron incompatibilidades de sintaxis durante la comprobación de actualización. Consulte el informe de comprobación de actualización para obtener más detalles.
Salvo en los escenarios anteriores, las Dynamic Tables de la V3.0 no requieren volver a crearse en Hologres V3.1. Sin embargo, solo se les puede aplicar ALTER DYNAMIC TABLE. La instrucción CREATE DYNAMIC TABLE (sintaxis anterior) no es compatible con la V3.1 ni versiones posteriores.
Límites
El comando de conversión de sintaxis solo funciona con tablas no particionadas, tanto incrementales como de actualización completa. Para las Dynamic Tables particionadas de la V3.0, vuelva a crearlas de forma manual.
Consultar las Dynamic Tables que requieren conversión de sintaxis
Busque las tablas de su instancia que necesitan conversión después de una actualización:
Tablas no particionadas
SELECT DISTINCT
p.dynamic_table_namespace as table_namespace,
p.dynamic_table_name as table_name
FROM hologres.hg_dynamic_table_properties p
JOIN pg_class c ON c.relname = p.dynamic_table_name
JOIN pg_namespace n ON n.oid = c.relnamespace AND n.nspname = p.dynamic_table_namespace
WHERE p.property_key = 'refresh_mode'
AND p.property_value = 'incremental'
AND c.relispartition = false
AND c.relkind != 'p';
Tablas particionadas
SELECT DISTINCT
pn.nspname as parent_schema,
pc.relname as parent_name
FROM hologres.hg_dynamic_table_properties p
JOIN pg_class c ON c.relname = p.dynamic_table_name
JOIN pg_namespace n ON n.oid = c.relnamespace AND n.nspname = p.dynamic_table_namespace
JOIN pg_inherits i ON c.oid = i.inhrelid
JOIN pg_class pc ON pc.oid = i.inhparent
JOIN pg_namespace pn ON pn.oid = pc.relnamespace
WHERE p.property_key = 'refresh_mode'
AND p.property_value = 'incremental'
AND c.relispartition = true
AND c.relkind != 'p';
Ejecutar la conversión de sintaxis
Notas:
Requisito de versión: V3.1.11 o posterior.
Requisito de rol: Superuser.
-
Cambios de comportamiento después de la conversión:
La actualización automática comienza de inmediato si el modo de actualización es
auto. Asegúrese de ejecutar esta operación fuera del horario de mayor demanda para evitar la contención de recursos. Para lograr un mejor aislamiento, utilice recursos de Serverless Computing.-
Cambios en el uso de recursos para instancias de almacén de datos virtual:
V3.1/V3.2 (nueva sintaxis): las Dynamic Tables en proceso de actualización consumen recursos de los almacenes de datos virtuales principales de los Table Groups correspondientes a las tablas base y dinámicas.
V3.0 (sintaxis heredada) y V4.1 (nueva sintaxis): las Dynamic Tables en proceso de actualización consumen recursos del almacén de datos virtual principal del Table Group de la Dynamic Table.
La nueva sintaxis agrega una conexión por cada Dynamic Table para la programación. Si su instancia tiene un alto consumo de conexiones, libere primero las conexiones inactivas.
Comandos:
-- Only for non-partitioned tables (full and incremental).
-- Convert a single Dynamic Table
call hg_dynamic_table_config_upgrade('<table_name>');
-- Convert all Dynamic Tables. Use with caution.
call hg_upgrade_all_normal_dynamic_tables();
Estos comandos convierten las Dynamic Tables (sintaxis anterior) de la base de datos actual a la nueva sintaxis.
Mapeo de parámetros de sintaxis
El comando asigna los parámetros y valores de la V3.0 y la V3.1 de la siguiente manera:
|
Sintaxis heredada (V3.0) |
Nueva sintaxis (V3.1+) |
Descripción |
|
|
|
El valor del parámetro se conserva tras la conversión. Por ejemplo, |
|
|
|
El valor del parámetro se conserva tras la conversión. |
|
|
|
El valor de Por ejemplo, |
|
|
||
|
|
|
El valor del parámetro se conserva tras la conversión. Por ejemplo, |
|
|
|
El valor del parámetro se conserva tras la conversión. |
|
|
|
El valor del parámetro se conserva tras la conversión. Por ejemplo, |
|
Propiedades de la tabla (por ejemplo, |
Propiedades de la tabla (por ejemplo, |
Las propiedades básicas de la tabla permanecen sin cambios. |
Referencias
Preguntas frecuentes
-
P: ¿Cómo soluciono el error relacionado con una clave de segmento o de agrupamiento nula? Ejemplo:
ERROR: commit ddl phase1 failed: the index partition key "xxx" should not be nullable Causa: la clave de segmento o de agrupamiento de una Dynamic Table no admite valores nulos. Para conocer las reglas de configuración de estas claves, consulte Event time column (segment key).
-
Solución:
-
Error de clave de agrupamiento: si usa una versión de Hologres anterior a la V3.1.26, V3.2.9 o V4.0.0, actualice su instancia y modifique el siguiente GUC para permitir una clave de agrupamiento que admita valores nulos:
-- For V3.1 and later ALTER DYNAMIC TABLE [ IF EXISTS ] [<schema>.]<table_name> SET (refresh_guc_hg_experimental_enable_nullable_segment_key=true); -
Error de clave de segmento: ejecute el siguiente comando para permitir una clave de segmento que admita valores nulos. A partir de Hologres V4.1, las claves de segmento permiten valores nulos de forma predeterminada, por lo que se recomienda actualizar la instancia para corregir el error.
--For V3.1 and later, allows a nullable clustering key ALTER DYNAMIC TABLE [ IF EXISTS ] [<schema>.]<table_name> SET (refresh_guc_hg_experimental_enable_nullable_clustering_key=true);
-