Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Sigo peleando con interbase (https://www.clubdelphi.com/foros/showthread.php?t=35287)

atani123 06-09-2006 13:04:37

Sigo peleando con interbase
 
Tengo una aplicacion que continuamente esta grabando informacion, aproximadamente 1 registro compuesto de unos 30 enteros cada minuto.
La aplicacion no se reinicializa nunca, es decir el pc esta encendido dias y dias con este proceso. Cuando cambia de dia los registros del dia anterior son borrados automaticamente.

Mi problema es el siguiente, ya expuesto en otro hilo sin encontrar solucion, La base de datos me llega a alcanzar 2GB en un par de dias, donde me dice que tengo 133548 paginas reservadas. De las que luego al hacer un backup y restore se me queda en 200 mas o menos. Existe alguna forma de eliminar estas paginas no usadas de una forma rapida. Podria realizar un backup/restore, pero el proceso que realiza el pc es muy critico, cada minuto exacto. No puedo entretenerlo mas de 20 seg.

No se que hacer

tulio 06-09-2006 13:15:10

Hola

te comento como hago algo parecido en SQL Server, en una situacion parecida a la que comentas, en vez de borrar los registros con delete ....
uso el comando truncate table, que te borra de raiz los registros .
No se si este comando esta en Interbases, seria bueno saberlo

saludos

tulio

Casimiro Notevi 06-09-2006 14:14:09

Cita:

Empezado por atani123
Tengo una aplicacion que continuamente esta grabando informacion, aproximadamente 1 registro compuesto de unos 30 enteros cada minuto.
La aplicacion no se reinicializa nunca, es decir el pc esta encendido dias y dias con este proceso. Cuando cambia de dia los registros del dia anterior son borrados automaticamente.

Mi problema es el siguiente, ya expuesto en otro hilo sin encontrar solucion, La base de datos me llega a alcanzar 2GB en un par de dias, donde me dice que tengo 133548 paginas reservadas. De las que luego al hacer un backup y restore se me queda en 200 mas o menos. Existe alguna forma de eliminar estas paginas no usadas de una forma rapida. Podria realizar un backup/restore, pero el proceso que realiza el pc es muy critico, cada minuto exacto. No puedo entretenerlo mas de 20 seg.

No se que hacer

La única forma de eliminarlas es haciendo un backup/restore.

Lo que te ocurre está provocado por el sistema de "multiversión" que usa interbase/firebird, llamado: "Arquitectura multigeneracional (MGA)", cada vez que insertas, modificas, etc cualquier registro, siempre se crea una copia (una versión del mismo) para el caso que luego hagas rollback o por si otro usuario está accediendo al mismo registro, etc. Esto permite un sistema multiusuario total sin los problemas de bloqueos que provocan otros sistemas de bases de datos.
Te recomiendo que leas el informe sobre transacciones del compañero Juan José Rodríguez.

Lo que cuentas ahora no es lo mismo que comentabas en el otro hilo, que por cierto, algún moderador te aconsejará que hubieses seguido el otro hilo en lugar de iniciar este nuevo. Pues lo que te comentaba: en el otro hilo decías que así porque sí, se ponía la base de datos a crear registros y no paraba hasta tener cientos de megas, algo que no tenía sentido y había sido el problema que he estado intentando resolver estos días contigo. Sin embargo, ahora dices que poco a poco, al cabo de los días, la base de datos ha aumentado de tamaño, o sea, no de golpe, como comentabas en el otro hilo.
Son dos cosas muy distintas, en el primer caso denota un problema, fallo o error de programación que inserta multitud de registros en plan "bestia". Lo que explicas en este hilo es, simplemente, normal.

Bueno, de todas formas, a lo que iba: si la base de datos va bien, responde bien, funciona correctamente, ¿qué importancia tiene que ocupe 2 gigas?.
Puedes seguir trabajando tranquilamente, haciendo backups online, no hay problema (precisamente gracias al sistema multigeneracional del que hablamos).

Si el problema es otro o si simplemente no te gusta que ocupe mucho la base de datos... entonces me temo que tendrás que cambiar a otra o inventar algún sistema de tablas temporales en memoria que se actualice cada cierto tiempo mientras se hace un backup/restore de la base de datos, etc.

En fin, que habría que estudiar a fondo el caso y conocer toda la problemática de la empresa para poder llegar a la solución adecuada.

Ya nos comentarás y perdona el "rollo" que he escrito :)

atani123 06-09-2006 14:43:15

No, Casimiro, me debo haber explicado mal.

En ningun momento la base de datos inserta registros porque si. Pero si que aumenta el tamaño de forma desproporcional y de un registro para otro.

Como comentaba voy insertando registros aprox. 1 cada minuto 1200 diarios, con muy poca informacion. Cada vez que inserto un registro sale una ventanita que pone "grabando datos", vale pues cuando lleva aprox 2 dias, la ventana esta se queda fija en pantalla, el codigo es algo asi:

frmventana.show
tabla.post
frmventana.hide

Entonces a traves del explorador miro la base de datos y su tamaño es desproporcional a la informacion que contiene (no es que tenga miles de registros, tendra aprox unos 2400). Unas veces me dice 500 MB otras 1,2 GB otras 2GB, cuando minutos antes su tamaño era correcto, unos 30 Mb.

Cierro la aplicacion a las bravas, compacto la base de datos y me la deja en eso unos 30 Mb, continua con el proceso y a los 2 dias lo mismo.

Casimiro Notevi 06-09-2006 15:18:11

Por cierto, ¿tienes habilitada escritura asíncrona?, prueba a cambiarla a síncrona, para que no lo almacene en la "cache´" y escriba directamente los datos a disco, así, en teoría debería de ir aumentando de tamaño la base de datos poco a poco, en lugar de cuando se llena la "caché" que lo graba todo de golpe.

Código:

/opt/firebird/bin/gfix -write  sync -user SYSDBA -password masterkey /home/datos/basedatos.fdb

jachguate 06-09-2006 15:32:45

  1. ¿Solamente ocurren inserciones o también ocurren actualizaciones de registros?
  2. ¿la base de datos tiene una sola tabla?
  3. ¿cuantos índices?
  4. ¿hay mas usuarios conectados al sistema?
  5. ¿hacen modificaciones?

MrDominoTk 06-09-2006 15:57:58

Esquivar el problema
 
Lo que se me ocurre, es que tengas 365 Base de datos, es decir 1 para cada dia. y ademas tener Otra BD maestra con aglutine datos al finalizar cada dia. una vez traspasado el dia anterior la borras.

Salu2 desde Chile.




Cita:

Empezado por Casimiro Notevi
Por cierto, ¿tienes habilitada escritura asíncrona?, prueba a cambiarla a síncrona, para que no lo almacene en la "cache´" y escriba directamente los datos a disco, así, en teoría debería de ir aumentando de tamaño la base de datos poco a poco, en lugar de cuando se llena la "caché" que lo graba todo de golpe.

Código:

/opt/firebird/bin/gfix -write  sync -user SYSDBA -password masterkey /home/datos/basedatos.fdb


atani123 06-09-2006 17:23:29

  1. ¿Solamente ocurren inserciones o también ocurren actualizaciones de registros?
No ocurren inserciones ni actualizacion. Yo soy quien inserta registros, solamente 1 por minuto, no se modifica nada.
  1. ¿la base de datos tiene una sola tabla?
Tiene varias tablas, nada del otro mundo, alrededor de 12 tablas, pero solo se inserta en una, las demas son maestras.
  1. ¿cuantos índices?
Aprox. 3 por tabla.
  1. ¿hay mas usuarios conectados al sistema?
No, trabaja en local, solo se conecta 1 usuario el SYSDBA
  1. ¿hacen modificaciones
No. Esta preparado para poderlas realizar pero es un proceso automatico que solo inserta.

Mas o menos es esto, una estacion meteorologica que registra la temperatura cada minuto. Posteriormente se podra consultar y demas, pero de momento tiene un timer que cada minuto mira el valor de la sonda y lo registra. Despues borra todos los registros en que la fecha < fecha-2dias.

jachguate 06-09-2006 18:18:04

Cita:

Empezado por atani123
Mas o menos es esto, una estacion meteorologica que registra la temperatura cada minuto. Posteriormente se podra consultar y demas, pero de momento tiene un timer que cada minuto mira el valor de la sonda y lo registra. Despues borra todos los registros en que la fecha < fecha-2dias.

Pues algo extraño debe haber... has hecho la prueba de registrar 1440 lecturas, pero no 1 cada minuto sino 1 cada segundo y ocurre lo mismo??

Has registrado el tiempo que tarda cada inserción?

Si todas van normales, debe haber una en particular que tome mucho tiempo... hacer crecer la base de 30Mb a 2Gb no es cosa de un segundo...

Es normal que una base de datos de firebird crezca mas allá de lo que se espera originalmente... pero el crecimiento en tu caso me parece descabellado. Se me ocurre que lances periodicamente un gfix -sweep sobre la base, pero si no hay modificaciones a los registros (updates), no hay razón para que haya basura en la base... solamente después del borrado.

¿cómo es el manejo de transacciones? ¿abris y cerras una transacción para insertar cada registro? ¿commit o commit retaining?

Hasta luego.

;)

Paoti 06-09-2006 18:49:48

es una suposición:

es probable que la applicación comience una trasacción y no la cierre, y abra ora, así anidandolas, o usando commit retaining, con lo cual no se cierra y firebird necesita tener el estado de todas sus trasacciones.

aledieb 06-09-2006 22:55:30

Solo una sugerencia, probaste utilizando directamente una sentencia sql con un query.

Código SQL [-]
insert into latabla (campo1,campo2) values (1,2)

Tal ves y solo tal ves sea un problema del componente que utilizas, por como hace la inserción del registro un ttable.

atani123 07-09-2006 08:44:47

A ver, a las preguntas, efectivamente hay un registro que tarda muchisimo en grabarse, tanto que debo hacer un down del servidor, este es que que me da el saldo de los 30Mb a los 2Gb, (que por cierto es un registro normal y corriente y no siempre es el mismo).

Efectivamente, utilizo el componente TIBTable para hacer las inserciones y el TIBQuery para el borrado de registros.

Despues de cada TIBTable.Post realizo un CommitRetaining.

El PC que tiene el problema lo tengo a 700Km de distancia, por lo que lo que he hecho ha sido restaurar una imagen Ghost en un PC que tengo en casa con la misma configuracion que el de mi cliente, pero cosas de la vida, aqui no me pasa el error.

El tiempo de las inserciones es normal, 1seg o menos aprox.


Gracias de nuevo

He probado metiendo un bucle infinito para añadir registros y nada, todo funciona OK.

Casimiro Notevi 07-09-2006 08:49:42

Hola, atani123, hice un programita con un timer que inserta un registro cada minuto, datos aleatorios, con la base de datos que me enviaste. Lo puse en marcha ayer, miércoles por la mañana, y de momento va creciendo poquito a poquito, lo voy a dejar funcionando durante este largo fin de semana (aquí es fiesta mañana viernes).
El lunes te cuento.

P.d.: si me dices exactamente qué tabla es en la que hay que insertar los registros, así hago una simulación lo más real posible con tu forma de trabajar, he elegido una tabla al azar, una que no tenía ningún registro.

La prueba es con Delphi 7 + FIBplus + Firebird 1.5 en servidor Suse Linux.

atani123 07-09-2006 09:20:14

Si, las tablas son Cero y CeroCar es un Master/Detail.

De todas formas yo lo he probado y me ha funcionado bien.

Casimiro Notevi 07-09-2006 09:36:19

Cita:

Empezado por atani123
Si, las tablas son Cero y CeroCar es un Master/Detail.

De todas formas yo lo he probado y me ha funcionado bien.

¿Qué quiéres decir con eso, que ya no tienes ese problema?, ¿ya lo solucionaste?


Edito: Ah, ok, no había leído tu mensaje anterior.

jachguate 07-09-2006 16:56:36

No veo sentido a usar un TIBTable, ni un commit retaining (aunque no veo también por que esto pueda causar el problema en cuestión). Creo que podes usar un TIbSQL y seguir el consejo de aledieb en cuanto a simplemente lanzar un insert into. También creo que debieras hacer un commit, dado que no hay razón para mantener abierta la transacción durante tanto tiempo...

Hasta luego.

;)

atani123 07-09-2006 17:18:49

El problema del commit es que me cierra la base de datos.

jachguate 07-09-2006 17:49:43

El commit no cierra la base de datos. Si usas IBX, te cierra los datasets asociados, comportamiento normal de interbase/firebird, y defecto de las IBX, que lo dejan todo crudo, tal cual es.

Sin embargo, para las tablas lookups, podes tener otra transaccion de solo lectura, por ejemplo, y una transacción para el insert. Por otro lado, haciendolo con un TibSQL, como te sugerí antes, no hay nada que cerrar, pues este se ejecuta y listo. :)

Hasta luego.

;)

atani123 12-09-2006 08:30:19

Atencion, mas informacion he puesto esta parte de codigo.

Código Delphi [-]
If dm.trsTransaction.InTransaction Then
Begin
nSize := GetFileSize( dm.IBDB.DatabaseName);
dm.trsTransaction.CommitRetaining;
AssignFile( pFile, 'C:\tamanos.txt');
If FileExists( 'C:\tamanos.txt') Then Append( pFile)
Else ReWrite( pFile);
Writeln( pFile, Format( 'Antes: %0.12d -> Despues: %0.12d = Incremento : %0.12d', [ nSize, GetFileSize( dm.IBDB.DatabaseName), GetFileSize( dm.IBDB.DatabaseName)-nSize]));
CloseFile( pFile);
End;

Resumo, lo que hace es mirar el tamaño de la base de datos antes del commitretaining, despues lo ejecuta y vuelve a mirar el tamaño. Luego almacena los tamaños en un fichero txt. Y este es el fichero obtenido despues de varias grabaciones.


Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040050688 = Incremento : 000000000000
Antes: 000040050688 -> Despues: 000040058880 = Incremento : 000000008192
Antes: 000040058880 -> Despues: 000041844736 = Incremento : 000001785856
Antes: 000041844736 -> Despues: 000043622400 = Incremento : 000001777664
Antes: 000043622400 -> Despues: 000045404160 = Incremento : 000001781760
Antes: 000045404160 -> Despues: 000047181824 = Incremento : 000001777664
Antes: 000047181824 -> Despues: 000048963584 = Incremento : 000001781760
Antes: 000048963584 -> Despues: 000050741248 = Incremento : 000001777664
Antes: 000050741248 -> Despues: 000052523008 = Incremento : 000001781760
Antes: 000052523008 -> Despues: 000054300672 = Incremento : 000001777664
Antes: 000054300672 -> Despues: 000056082432 = Incremento : 000001781760
Antes: 000056082432 -> Despues: 000057860096 = Incremento : 000001777664
Antes: 000057860096 -> Despues: 000059641856 = Incremento : 000001781760
Antes: 000059641856 -> Despues: 000061419520 = Incremento : 000001777664
Antes: 000061419520 -> Despues: 000063201280 = Incremento : 000001781760
Antes: 000063201280 -> Despues: 000064978944 = Incremento : 000001777664
Antes: 000064978944 -> Despues: 000066760704 = Incremento : 000001781760
Antes: 000066760704 -> Despues: 000068538368 = Incremento : 000001777664
Antes: 000068538368 -> Despues: 000070320128 = Incremento : 000001781760
Antes: 000072101888 -> Despues: 000072101888 = Incremento : 000000000000
Antes: 000072101888 -> Despues: 000073883648 = Incremento : 000001781760
Antes: 000073883648 -> Despues: 000075665408 = Incremento : 000001781760
Antes: 000075665408 -> Despues: 000077447168 = Incremento : 000001781760
Antes: 000077447168 -> Despues: 000079224832 = Incremento : 000001777664
Antes: 000079224832 -> Despues: 000081006592 = Incremento : 000001781760
Antes: 000081006592 -> Despues: 000082788352 = Incremento : 000001781760
Antes: 000082788352 -> Despues: 000084570112 = Incremento : 000001781760


Antes del commitretaining se realiza el post de 3 tablas. He probado a eliminar 2 y dejar solamente un post y el resultado es el mismo, solo que al principio en vez de haber n registros que no incrementan tamaño han habido n*3 registros que no incrementan. Luego todo igual.

jachguate 12-09-2006 15:57:20

Ahora vemos que la base de datos no crece de tajo... como se había creido al principio.

Sigo creyendo que el commit retaining tiene algo que ver en este caso... pero no logro imaginar cómo, suponiendo que tenes un tamaño de página de 4K, el sistema se dispara 436 páginas solamente después de insertar 3 registros.

Si no queres hacer cambios en el commit, yo probaría poniendo un tamaño de página mas pequeño... quizas eso ayude.

Hasta luego.

;)


La franja horaria es GMT +2. Ahora son las 09:43:41.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi