Hola Lista, disculpen la extension del correo, solo intento comentar mis experiencias positivas y negativas para que aprendan de mis errores o me sugieran/comenten lo que consideren.
La version que estoy usando es 9.3.23. Cuando el servidor dejo de aceptar conectiones de escrutura para evitar el wraparound pudimos conectarnos en el mudo single-user, a la base de datos que decia en el error. Se le ejecuto un vacuum a esa base de datos y lo reiniciamos, pero todas las base de datos estaban asi, por lo que tuvimos que apagarlo nuevamente y ejecutar vacuum a todas las base de datos. En la ultima y mas grande, despues de 7 horas de vacuum en single-user decidimos detener el proceso de vacuum que estaba ejecutando, como estabamos en single-user decidimos unsar un Kill pid, el cual no funciono por lo que fuimos mas drasticos y usamos kill -9 pid, desgracuadamente esto nos cobro factura al tratar de levatar el servicio despues, pues se demoro alrededor de 30 min levantarlo. Asi que si exiate otra manera de detener este servicio cuandonse este ejecutando single-user seria genial. Despues que postgres finalmente volvio a estar en servicio, empece a revisar las tablar con mayor frozenxid y empece a ejecutar vacuum lograndolo bajar considerablemente (478 millones). Mi enfoque de trabajo estubo: 1. encontrar la base de datos con mayorr datfrozenxid usand; 2. buscar en esta base de datos las tablas con mayor relfrozenxid. 3. Ejecutar vacuum en esas tablas. Algo curioso salio en el proceso, y es que template0 es la "base de datos" con mayor datfrozenxid, me lleve una sorpres cuando trate de conectarme para ejecutar vacuum y no pude, pero en postgres.org en el apartado de mensajes y respuestas encontre informacion diciendo que no te puedes conectar y que postgres o vheckea el datfrozenxid y que autovacuum se encargaria de todas formas por si acaso...en fin...la documentacion que he encontrado no me ha dejado claro como postgres trata esta BD y si puede representar un peligro nuevamente. Aproveche este suceso lamentable para cambiar algunos parametros en la configuracion de postgres que requerian reiniciar el servidor: hacer mas agresivo autovacuum autovacuum_max_workers: 6 autovacuum_vacuum_cost_limit: 1500 y enfoque autovacuum en tablas mas grande modificando scaler_factor y threshold.. Tambien incremente shared_buffer a 32GB max_locks_per_transaction 1024 Cuando pensaba que la tormenta habia pasado, recivimos una alerta de new relic con un aumento extremo en wl tiwmponde respuesta de la aplicacion por culpa del servidor de base de datos, disminui el cost_limit a 400, y recargue la configuracion y seguia aumentando el tiwmpo de respuesta. Chequeando pg_stat_activity me percado de que muchas queries estaban escribiendo aobre la misma tabla, revise por exclusived/dead locks y no habian, la unica solucion que encontre fue detener el autovacuum por 45 minutos hasta que el tiempo de respuesta se restableciera, apagandolo encontre unos deadlocks loa resolvi y tudo funciono como lo esperado, despues de 45 min volvi a encender el autovacuum y todo ha estado funcionando correctamente. Desgraciadamente aun mantengo el cost_limit a 400 no quiero aumentarlo y contribuir nuevamente a un cuello de botella de I/O que es lo que creo que sucedio. Sabemos que tenemos algunos problemas de arquitectura del software como se esta escribiendo en la base de datos, pero ahora mismo el codigo y la arquitectura no se va a tocar. Las medidas y metas propuestas a corto plazo son: 1.Migrar a 9.6 en un servidor muchooo mas potente que el actual con 5T SDS interno. 2.Recisar la configuracion de connection pool de Ruby/Rails y tratar de usarlo o optimizarlo pues esta por defecto. 3.Optimizar las consultas y tratar de usar algunas vistas materializadas donde sea oportuno. 4.Configurar el freeze setting the postgres 5.Eecutar vacuum siempre que sea posible en momentos de baja carga, hasta que logremos migrar y aumentar el numero de trabajadores de autovacuum y el cost_limit. Por cierto sobre vacuum hay algo extra que les quiero comentar, ejecutamos un vacuum analyze verbose a una de las base de datos y durante este momento un trabajo automatico se realizo, y postgres decia que no tenia suficiente shared memory despues que lw subi a 24GB el shared_buffer y a 4GB el maintenance_work_mem, el trabajo consitis en ejecutar unos ficheros para salvar informacion en la base de datos y se perdio informacion durante el proceso. es posible que: insertar trabajador 1 hay shared memory no hay problema. insertar trabajador 2, no hay shared memory pues no se inserta y se pasa al siguiente trabajador. insertando solo aquellos trabajadores de la lista cuando hubo shared memory, y si no habia se perdia esa informacion...? Ah, alguien me pregunto si usaba tablas particionadas y si, uso particionamiento por fecha y tambien por lista algo asi que cada cliente tiene su propia particion de la tabla tabla_x, y casualmente en esa tabla_x es donde mas operaciones de escritura se realizan. Saludos, Carlos.