Tengo una base de datos con una gran cantidad (3000+) de esquema idéntico en estructura. Estoy tratando de eliminar dos tablas de cada esquema. Así que escribí una función que recorrerá el esquema e intentará eliminar esas tablas.
Cuando ejecuto mi función obtengo ERROR: fuera de la memoria compartida y no se descartan tablas.
¿Existe la posibilidad de obligar a PostgreSQL a confirmar las declaraciones de la tabla desplegable en lotes?
Aquí está mi función (simplificado al problema en cuestión):
CREATE OR REPLACE FUNCTION utils.drop_webstat_from_schema(schema_name character varying default '') RETURNS SETOF record AS $BODY$ declare s record; sql text; BEGIN for s in select distinct t.table_schema from information_schema.tables t where schema_name <> '' and t.table_schema = schema_name or schema_name = '' and t.table_schema like 'myprefix_%' loop sql := 'DROP TABLE IF EXISTS ' || s.table_schema || '.webstat_hit, ' || s.table_schema || '.webstat_visit'; execute sql; raise info '%; -- OK', sql; return next s; end loop; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100 ROWS 1000;Como puede ver, la función recorre el conjunto de esquemas y, para cada esquema, se construye el siguiente SQL y luego se ejecuta.
DROP TABLE IF EXISTS <schema_name>.webstat_hit, <schema_name>.webstat_visitSupongo que PostgreSQL está tratando de bloquear todas esas tablas antes de soltarlas y alcanzó el límite máximo configurado. Probablemente, si aumento max_locks_per_transaction a un cierto número fijo, podría bloquear todas las tablas y eliminarlas.
Pero estoy buscando una solución que suelte tablas en pasos y bloquee solo esas tablas dentro del paso . Como por cada 10 esquemas, bloquee y suelte un lote.
¿Puedo hacer eso en PostgreSQL y, de ser así, cómo? Gracias.
Quitaría el bucle de esquema de la función con gotas.
Así que supongamos fn_loop repite los esquemas y llama a fn_drop . Puede confirmar en lotes en plpgsql si ejecuta fn_drop sobre dblink.
Otra forma de tener compromiso entre esquemas, bucle en bash, por ejemplo:
for i in $(psql -c "select nspname form pg_namespaces where blah blah"); do psql -c "drop damn table"; done;ejemplo de llamadas locales en transacciones diferentes con dblink (observe la diferencia en now() en la misma base de datos):
t=# do $$ declare _t text; begin for _r in 1..2 loop select t into _t from dblink('dbname=t'::text,'select now()::text'::text) rtn (t text); raise info '%',concat('local: ',now(),', dblink: ',_t); end loop; end; $$ ; INFO: local: 2017-04-28 07:38:11.352026+00, dblink: 2017-04-28 07:38:11.355149+00 INFO: local: 2017-04-28 07:38:11.352026+00, dblink: 2017-04-28 07:38:11.358211+00 DO Time: 6.811 ms