Saludos.

    Revisando en las entreñas de las tablas involucradas he decubierto lo que explica el problema. Los campos de tipo "serial" son creados como "integer" el problema es que los valores asinados a la sequence (MAXVALUE), no son soportador por este tipo de dato.


Valor por defecto para una sequence:
MAXVALUE 9223372036854775807

Maximo en un campo integer:
2147483647

Solucion: cambiar los campos afectado por la sequence a "bigint", o al crear la tabla usar "bigserial" en vez de "serial"


;)

Atento a sus comentarios.


Javier Fritz Alsite wrote:
Hola

    Con el cambio que propuso Mariano mejoro el panorama, con las indicaciones dadas el query generado si es correcto y al ejecutarse el query la "L" desaparece ;).

    El problema ahora esta en el trigger pero del esclavo, al hacer el cambio en el maestro, el trigger genera ok el query en el replica_log (maestro), este es capturado por el esclavo (que a su vez es maestro), lo ejecuta y el triger captura el cambio en la tabla, pero al insertar el registro en replica_log envia el siguiente mensaje:

Traceback (most recent call last):
  File "/usr/local/pyreplica/daemon.py", line 74, in run
    debug = self.debug)
  File "/usr/local/pyreplica/pyreplica.py", line 154, in main_loop
    replicate(cur0, cur1, skip_user, slave_field, debug)
  File "/usr/local/pyreplica/pyreplica.py", line 92, in replicate
    cur1.execute(sql)
DataError: el entero está fuera de rango
CONTEXT:  sentencia SQL: «INSERT INTO replica_log (sql) VALUES ($1)»

Buscando en el log de pyreplica en el esclavo encontre el query que se trae del maestro y al ejecutarlo manualmente sobre el esclavo envia:

WARNING:  plpython: in function py_log_replica:
DETAIL:  plpy.Error: Unknown error in PLy_spi_execute_plan

ERROR:  el entero está fuera de rango
CONTEXT:  sentencia SQL: «INSERT INTO replica_log (sql) VALUES ($1)»

********** Error **********

ERROR: el entero está fuera de rango
SQL state: 22003
Context: sentencia SQL: «INSERT INTO replica_log (sql) VALUES ($1)»


$1 corresponde al query que se ha ejecutado sobre una de las tablas del sistema, y segun la definición de la tabla el unico campo que puede dar este problema corresponde a "id" ya que es un serial. La seq. relacionada es

CREATE SEQUENCE replica_log_id_seq
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 3223372036854776031
  CACHE 1;

el valor dudoso es start, pero fue dado en base a las recomendaciones del manejo de sequencias para pyreplica (no se excluyo a replica_log) a este esclavo le corresponderia trabajar en el segundo tercio del rango.

Por ahora se me ocurre vaciar el replica log del esclavo y restablecer la seq.

atento a sus comentarios.

Saludos.
  



Javier Fritz Alsite wrote:

lo estoy probando en este instante te cuento el resultado
Gracias :)



Mariano Reingart wrote:
2009/10/2 Javier Fritz Aliste <javier.fritz@lanix.cl>
Hola.

    Como estan, hace algun tiempo pedi ayuda sobre una solución de replicación, he optado por PyReplica , y tengo el siguiente problema.quizas de simple la solución,

    Tengo 3 servidores, cada uno tiene conexión con dos maestros remotos, funciona aceptablemente bien, esta montado en servidores con salida a internet con un trafico aun de prueba.

    Al grano, al  realizar una insercion en una tabla que posee un campo bigint, el triger esta capturando el query pero para el valor de este campo lo concatena con "L", no se si esto es correcto, ya que al ejectuar este query, se por el esclavo  pyreplica o extrayendolo manualmente y ejecutandolo sobre la base genera el error.


Hola Javier, parece ser un tema de conversión entre postgresql y python, una solucion podria ser modificar el código del disparador en plpython para que detecte los bigint de pg (long en python) y no le agregue la L al convertirlos para el query sql:

  # function to convert value from python to postgres representation
  def mogrify(v):
    if v is None: return 'NULL'
    if isinstance(v,long): return str(v) # no agregar L a long (bigint)
    if isinstance(v,basestring):
       r = repr(v)
       if not r.startswith('\"'):
          return r
       else:
          # postgres doesn't support ", replace and escape '
          return "'%s'" % r.replace("'","\\'")[1:-1]
    return "'%s'" % repr(v) # to get rid of bool that are passed as ints (solved in pg8.3)

Lo que hay que agregar es la linea verde despues de if v is None.. (respetando la identación):
if isinstance(v,long): return str(v)

No lo probé pero tendría que funcionar, cualquier cosa avisame
Sds
Mariano