Ir al contenido

Actualizar

Instala la versión nueva como se instaló la anterior, encima de ella, y vuelve a arrancar el colector. La configuración, el fichero de estado y el registro de escrituras pasan tal cual, y no hay nada que migrar a mano. Lo que sigue es cómo son las primeras horas tras la actualización, para que nada de ello parezca una avería, y lo poco que merece la pena hacer al respecto.

Los dashboards se generan desde el binario, así que vuelve a publicarlos tras una actualización, con -publish-dashboard o grafana.publish_on_start: ver dejárselo al binario.

A veces una versión cambia la clave de una fila guardada. Lo habitual es una etiqueta que pasa a ser campo: cada fila escrita antes del cambio es una serie distinta de las escritas después, así que el almacén guarda las dos para siempre, y un recuento sobre ellas crece en uno por cada elemento leído a los dos lados del cambio. El binario lleva la lista de todos los cambios así que todavía puede guardar un almacén escrito por una versión 2.x, cada uno con un ID que nombra la versión y la medida, como 2.6.1/gh_discussion_comment/is_answer, y -migrate contrasta con ella cada almacén configurado:

Ventana de terminal
ghchronicle -config /etc/ghchronicle/config.yaml -migrate

Imprime un bloque por almacén y una línea por cambio, y no cambia nada: a los almacenes se les hacen preguntas, a GitHub solo se le pide la lista de repositorios, y el fichero de estado se lee y nunca se escribe. Un almacén al que se le puede preguntar decide por sí mismo; uno al que no, lo decide lo que el fichero de estado recuerda de él.

AlmacénQué decide
InfluxDB 3Si la etiqueta antigua es una columna de etiqueta de la tabla viva, según el catálogo. Una tabla que InfluxDB ha apartado aparece con otro nombre y no se pregunta
InfluxDB 2Si alguna fila lleva la etiqueta antigua. Las claves de etiqueta siguen listadas tras un borrado, así que no se preguntan
PostgreSQLSi alguna fila tiene un valor en la columna de la etiqueta antigua, en el esquema donde escribe el destino
ElasticsearchUn recuento de los documentos que llevan la etiqueta antigua. El mapping conserva un campo después de irse sus documentos
Fichero SQL, Graphite, TelegrafLa versión que el fichero de estado registra como la primera que escribió en el almacén
Loki, Prometheus, OTLP, file, stdoutNada: ninguno guarda una fila cuya identidad pueda cambiar una versión

Cada línea empieza por lo que encontró la comprobación:

  • not needed: el almacén no guarda nada de la forma antigua.
  • pending: guarda la forma antigua o, en un almacén al que no se le puede preguntar, puede guardarla. Las líneas de debajo dicen por qué, qué haría allí ponerlo al día, qué familias volverían a leer la medida y desde cuándo, y lo que no volvería: las filas de repositorios que la configuración ya no cubre y las de familias que tiene apagadas. En los comentarios, esas son los comentarios de otros en un repositorio así: los de la propia cuenta vuelven a través de outbound estén donde estén. La última línea dice si aplicarlo no necesita la palabra de nadie: GitHub todavía sirve toda la historia, así que volvería cada fila que guarda el almacén, las filas antiguas se apartarían al menos 24 horas en vez de borrarse, y todas las filas del almacén son de esta configuración. Un almacén compartido con otro colector, uno que guarda filas que la relectura no traería de vuelta, uno cuyas filas no se pudieron comparar con la configuración, un InfluxDB 2, cuya única vía es un borrado, y todo almacén al que no se le puede preguntar necesitan la palabra de alguien, y la línea dice qué razón aplica. Una fila que no nombra ninguna cuenta es de una configuración solo de organizaciones, que no escribe usuario: es de esta configuración solo cuando esta tampoco tiene targets.user.
  • note: las filas están ahí y nada puede arreglarlas, así que el plan dice qué significan y no cambia nada.
  • frozen: nada de lo que ejecuta esta configuración escribe ya la medida, así que sus filas son historia y se dejan como están.
  • applied: el fichero de estado registra el cambio como aplicado a este almacén, y el almacén, si se le puede preguntar, está de acuerdo.
  • unreachable: el almacén no respondió, así que no se sabe nada de él.

Toda ejecución que escribe en los almacenes, el servicio, -once, -backfill y una tarjeta dibujada junto a los almacenes, los comprueba igual antes de su primera pasada, y lo que hace después lo decide el ajuste migrate:

  • auto, el valor por omisión, aplica por su cuenta cada cambio pendiente marcado como seguro de aplicar sin supervisión, y nada más. Primero lo dice, en WARN, con lo que encontró, por qué existe el cambio y qué hace en ese almacén, incluido dónde se apartan las filas antiguas; después vuelve a leer la medida de GitHub, y solo entonces hace la pasada.
  • warn no aplica nada.

Una ejecución de una sola vez, -once o -backfill, sobre un fichero de estado nuevo tampoco aplica nada por su cuenta bajo auto, y avisa en su lugar. Esa es cada ejecución de la Action que no restaura su fichero de estado con actions/cache, cuyo fichero de estado se va con su runner, y con él el registro de que aún se debe una relectura: una relectura que falló, o un job cancelado a medias, dejaría el almacén despejado y nada en ninguna parte que lo dijera. La siguiente ejecución en una máquina, que para entonces tiene fichero de estado, o -migrate -yes, lo aplica.

Un cambio pendiente que un arranque no aplica es un WARN en cada arranque, con el almacén, la razón por la que se dejó y las dos órdenes, copiadas de la configuración que recibió la ejecución. Una línea en el registro, partida aquí:

level=WARN msg="migration pending" sink=graphite measurement=gh_discussion_comment
migration=2.6.1/gh_discussion_comment/is_answer why="is_answer was a tag, ..."
not_applied="only whoever runs the Graphite host can remove its files"
plan="ghchronicle -config /etc/ghchronicle/config.yaml -migrate"
apply="ghchronicle -config /etc/ghchronicle/config.yaml -migrate -yes"
first="stop this service: -migrate -yes refuses to run beside it"

No hay ajuste que aplique el resto por su cuenta: un cambio que podría perder filas espera a que alguien lea el plan y dé su palabra. Una nota se dice una vez en INFO y después en DEBUG, porque nada la cambiará nunca, y lo mismo un cambio cuya medida ya no escribe nada de lo que ejecuta la configuración. Un almacén que no responde en 30 segundos también es un WARN, y la pasada sigue sin esperar más.

Lo que un arranque encuentra innecesario, y lo que ha aplicado, lo registra, y el siguiente arranque se fía del registro: una vez resuelto cada cambio de un almacén, un arranque no le pregunta nada a ese almacén. -migrate no se fía de ese registro y vuelve a preguntar cada vez.

Ventana de terminal
systemctl stop ghchronicle
ghchronicle -config /etc/ghchronicle/config.yaml -migrate -yes
systemctl start ghchronicle

Ejecútalo con el usuario con que corre el servicio y con el entorno que tiene el servicio: guarda el fichero de estado y los que hay a su lado, y un fichero que guarda root es uno que el servicio ya no puede leer. Una ejecución que encuentra el fichero de estado y no puede leerlo, o no puede analizarlo, se detiene y lo nombra en vez de empezar con uno nuevo, que olvidaría una relectura aún debida: devuélvele el fichero al usuario del servicio. systemd y Docker muestran cómo.

Pausa también un cron o un temporizador que ejecute -once, y deja terminar antes un -backfill que esté en marcha. Ninguno tiene el bloqueo mientras hace su pasada, y un fichero SQL que escriben dos procesos a la vez no es uno que psql pueda reproducir. Su fichero de estado está a salvo en cualquier caso: una ejecución que lo guarda conserva lo que otro proceso registró de los almacenes desde que ella lo leyó, así que un -once que corrió a la vez que -migrate -yes no devuelve el registro que había leído antes.

-migrate -yes imprime el mismo plan y después aplica cada cambio pendiente, también los que no son seguros, porque -yes es la palabra que pedía el plan. Cada uno se registra en el fichero de estado al aplicarse, así que parar a medias no cuesta nada que la siguiente ejecución no pueda retomar: lo aplicado no se hace dos veces. Una línea bajo el plan dice qué pasó con cada uno:

  • applied: hecho. Donde se guardan las filas antiguas, las nombra; donde tiene que actuar otro, en un servidor de Graphite o detrás de un Telegraf, imprime las órdenes que hay que ejecutar allí.
  • failed: el almacén se negó, con su razón. Los demás siguen adelante.
  • held back: el almacén guarda filas de cuentas que esta configuración no recoge, o de quién son sus filas no se pudo comparar con esta configuración, y la línea dice cuál y por qué. Apartadas, las filas de otro solo vuelven cuando quien las recoge las lee de nuevo, así que esto lleva -migrate-others además de -yes.
  • unreachable: el almacén no respondió, así que allí no se hizo nada.
  • refill: qué se volvió a leer de GitHub, desde cuándo y en qué almacenes, o por qué la relectura no terminó: ver volver a leer el historial.
  • reconciled: cada copia de las filas antiguas comparada con lo que volvió, y los elementos que GitHub ya no sirve.

Sale con 0 cuando todo lo pendiente se aplicó y se volvió a leer, y con 1 cuando quedó algo, con la frase que dice cómo seguir. Se niega antes de cambiar nada, y sale con 1, sin token de GitHub o sin lista de repositorios, porque nada de lo que despeja podría volver a leerse, y mientras otro proceso tiene el fichero de estado: el servicio lo tiene mientras corre, junto al fichero de estado como <nombre>-lock, y -migrate -yes nombra ese proceso en vez de cambiar los almacenes en los que escribe. Un servicio arrancado mientras corre -migrate -yes espera a que termine, y un segundo servicio sobre el mismo fichero de estado se rechaza.

En la GitHub Action, mode: migrate ejecuta -migrate -yes: ver las entradas.

AlmacénQué hace aplicarlo
InfluxDB 3Borra esa tabla, que InfluxDB guarda como <medida>-<instante>, consultable, y purga él mismo 72 horas después, o nunca antes de la 3.2
InfluxDB 2Borra todas las filas de la medida en el bucket. No se guarda nada, así que un arranque nunca lo hace por su cuenta
PostgreSQLRenombra la tabla <medida>-<instante> en el esquema del destino; ghchronicle la borra 24 horas después
ElasticsearchBloquea las escrituras del índice, lo clona a <índice>-<instante> y lo borra; ghchronicle borra el clon 24 horas después
Fichero SQLEscribe DROP TABLE IF EXISTS de la medida en el fichero, antes de las filas escritas después
GraphiteImprime las órdenes que quitan las rutas antiguas en la máquina de Graphite
TelegrafDice qué hacer en el almacén que tiene detrás

Cada almacén toca esa medida y nada más: la tabla, el índice o las rutas nombrados exactamente, en la base de datos, el bucket, el esquema o el prefijo en el que escribe el destino. Una medida que se le parece, las tablas de otro colector y los índices de otro prefijo no se alcanzan nunca. Un almacén al que se le puede preguntar solo se cambia después de preguntarle y encontrar que guarda la forma antigua, y una prueba en seco no le envía más que preguntas.

Donde un almacén guarda aparte las filas antiguas, el plan nombra cada copia bajo el almacén, con una línea kept aside que dice cuándo se apartó y cuándo se va, y el fichero de estado la guarda hasta entonces. ghchronicle purga sus propias copias cuando llevan 24 horas guardadas: el servicio tras una pasada, cualquier ejecución en su siguiente arranque, y -migrate -yes cada vez que se ejecuta. Una ejecución sobre un fichero de estado nuevo, entre ellas cada ejecución de la Action que no restaura uno, pregunta a PostgreSQL y a Elasticsearch por las copias con el nombre que les da una migración, porque su fichero de estado no puede nombrarlas. InfluxDB 3 purga las suyas con un calendario propio, que se lee de la tabla de sistema de su base de datos _internal: 72 horas después del borrado por omisión (medido de la 3.2.1 a la 3.11.5), y guarda el nombre en su catálogo durante su periodo de gracia de borrado después de eso, 24 horas por omisión. Un servidor anterior a la 3.2 no purga ninguna: el plan lo dice antes de aplicar, y -migrate pregunta al servidor por cada copia que guarda así, con la petición que la quita en cuanto el servidor ejecute una versión de la 3.2 a la 3.9 (ver antes de la 3.2 la copia se queda). Hasta que una copia se va, cómo deshacer el cambio está en la página de cada almacén.

Un almacén despejado se vuelve a escribir entero. El registro de escrituras olvida la medida solo en ese almacén, y cada otra medida y cada otro almacén conservan lo que recuerdan, y el fichero de caché olvida lo que afirma de las familias que escriben la medida, sus rechazos y, cuando actions está entre ellas, las ejecuciones de workflows cuyos jobs había escrito, así que las pasadas siguientes preguntan todo lo que pregunta una primera pasada.

Un almacén despejado no guarda nada del historial de la medida hasta que se vuelve a leer de GitHub. Justo después de aplicar, la misma ejecución lo lee de nuevo con un relleno histórico propio, la relectura: las familias que escriben la medida, discussions y outbound para los comentarios, security para los elementos de alerta, y ninguna otra; escribiendo solo esa medida; en los almacenes que se despejaron y en ningún otro.

refill read discussions and outbound again, since 2023-11-14, writing gh_discussion_comment to
elasticsearch, influxdb and postgres
  • Solo lo que se despejó. Una familia pregunta a GitHub todo lo que pregunta siempre, y solo se escribe la medida despejada; el resto de lo que recoge la familia ya está en los almacenes. Cada almacén recibe lo que se despejó en ese almacén, así que a un almacén que aún guarda una medida con su forma antigua nunca se le entrega el historial de esa medida al lado.
  • Solo donde se despejó. InfluxDB, PostgreSQL, Elasticsearch, el fichero SQL, después de su DROP, y Graphite, a la profundidad nueva. Nunca Loki, el exportador de Prometheus, OTLP, el destino de fichero ni stdout, que no se despejaron y guardarían cada fila de la relectura dos veces, ni un Telegraf, cuyo almacén es de otro: el plan nombra el -backfill -families que envía el historial a través de él cuando ese almacén se haya despejado.
  • Tan atrás como llegaba el almacén. El día de la fila más antigua que guardaba el almacén, leída antes de despejarlo: un límite posterior perdería la diferencia para siempre cuando se purgue la copia. Un almacén que no puede decir hasta dónde llegan sus filas, el fichero SQL, Graphite o un InfluxDB 3 Core que no quiso contarlas (abajo), se relee sin límite: lo que se lleva aplicarlo allí es cada fila sea cual sea su fecha, y backfill.since acota lo que alcanza un relleno histórico, no lo que guarda un almacén. Una relectura para varios almacenes llega tan atrás como el que más.
  • Esperando, como espera un relleno histórico. Tiene un cliente de GitHub propio que espera a que se renueve un límite de peticiones gastado, donde una pasada lo salta, y -backfill-retry vuelve a por lo que deja igual que en un relleno histórico. El -migrate -yes entero de la batería con contenedores, que despeja InfluxDB 3.11.2, PostgreSQL 18.6 y Elasticsearch 9.5.3 y vuelve a leer los comentarios del GitHub falso, tarda unos 2 segundos; en la cuenta del autor, el recorrido de outbound que necesita tardó 33 segundos cuando el de la 2.6.1 se hizo a mano.

La relectura se debe antes de tocar un almacén, y el fichero de estado lo registra entonces, bajo la clave refill del almacén: un almacén despejado y no releído parece, a quien le pregunte, exactamente uno que nunca guardó la forma antigua, y solo ese registro dice que el historial aún está por llegar. Un despeje que falló y dejó el almacén como estaba, lo que dice el almacén, retira la deuda; uno cuya respuesta no llegó, un 502 de un proxy o un tiempo agotado, se vuelve a mirar, y cuando el almacén no puede decir si se llevó a cabo la relectura sigue debiéndose, lo que como mucho lee el historial una vez para nada. Se va cuando la relectura llega al final de todas las familias. Una relectura cortada, por una parada, un almacén que rechazó una escritura o un GitHub que no respondió, guarda un punto de control propio junto al fichero de estado, con -refill.json en el nombre, aparte del de un relleno histórico para que ninguno rechace ni pise al otro, y se retoma desde ahí: con -migrate -yes otra vez, aunque no quede nada por aplicar, y con cualquier arranque bajo migrate: auto. Bajo migrate: warn un arranque dice que se debe, en cada arranque, con la orden. -backfill-status imprime hasta dónde ha llegado, y -migrate la lista bajo su almacén como refill owed.

Bajo migrate: auto el servicio aplica lo seguro y lo vuelve a leer después de construir sus destinos y antes de su primera pasada, así que sus pasadas empiezan cuando termina la relectura. El exportador de Prometheus está levantado durante ese tiempo y no guarda nada hasta la primera pasada, como tras cualquier reinicio. Un servicio parado durante la relectura sale en el acto, conservando lo que escribió, y su siguiente arranque continúa. El registro de escrituras recuerda lo que escribió la relectura, así que la primera pasada tras ella no vuelve a enviar esas filas. Bajo migrate: warn no se relee nada y el servicio hace sus pasadas como siempre, escribiendo la forma de esta versión junto a la antigua, y -migrate -yes se niega a correr a su lado.

Una relectura trae de vuelta lo que GitHub aún sirve para los objetivos configurados ahora. Cuando termina, cada almacén que guardó una copia de las filas antiguas y al que se le puede preguntar, InfluxDB 3, PostgreSQL y Elasticsearch, compara la copia con la tabla, elemento a elemento: el comment de cada comentario, el full_name y el number de cada alerta. Lo que guarda la copia y no la tabla es lo que GitHub ya no sirvió, un repositorio borrado o que ya no se cubre, un comentario borrado, una alerta cuya función se apagó; el informe y el registro nombran unos pocos, y esas filas quedan solo en la copia hasta que se purga. De la batería con contenedores, cuyo comentario sembrado no sirve el GitHub falso:

reconciled gh_discussion_comment in postgres: 1 item in gh_discussion_comment-20260928T234418, 6 now; 1 GitHub
no longer serves, whose rows are only in the copy until it is purged: 1

Traspasarlas queda en manos del lector, desde la copia, mientras está: para un elemento cuya forma antigua eran dos filas en un mismo instante, cuál de las dos era la buena no es algo que un programa pueda saber sin conexión. Medido en solo lectura contra el InfluxDB 3.11.5 de producción, la copia que guardó InfluxDB de la tabla borrada a mano para la 2.6.1 tenía 114 comentarios, y la tabla releída 121, sin que faltara ninguno de los 114.

El límite de ficheros por consulta de InfluxDB 3 Core

Sección titulada «El límite de ficheros por consulta de InfluxDB 3 Core»

InfluxDB 3 Core rechaza una consulta que abriría más ficheros Parquet que su --query-file-limit, 432 por omisión, y una tabla que una pasada escribe cada diez minutos lo supera en días. La comprobación lee el catálogo, que no abre ningún fichero, así que sigue encontrando la forma antigua en una tabla así, y una tabla sin etiqueta antigua no se cuenta en absoluto. Lo que no puede hacer allí es contar las filas, lo que deja la relectura sin límite, ni leer de quién son las filas de la tabla, lo que deja el cambio necesitando tu palabra y a -migrate -yes reteniéndolo a la espera de -migrate-others; el plan cita el rechazo del servidor. Medido en 3.11.2 con el límite bajado a 3: antes de esto, la misma tabla era unreachable en cada arranque y -migrate -yes no podía aplicarlo en absoluto. Subir el límite en el servidor, mientras dura la migración, le deja responder a todo.

Lo que el fichero de estado recuerda de cada almacén

Sección titulada «Lo que el fichero de estado recuerda de cada almacén»

La clave stores del fichero de estado guarda, para cada almacén en el que escribe una ejecución, adónde apunta, la versión que escribió en él primero y la que lo hizo por última vez. Un primer arranque, sobre un fichero de estado sin historia, registra la versión en marcha como la primera que escribió en cada almacén, así que una instalación nueva no tiene nada que migrar. El primer arranque tras actualizar desde la 2.6.1 o anterior registra la primera versión como desconocida, lo que para un fichero SQL, un Graphite o un Telegraf se lee como anterior a cualquier cambio, así que esos muestran cada cambio de una versión 2.x como pendiente, o como nota donde nada puede arreglarlo, hasta que se aplique. Un destino apuntado a otro almacén empieza un registro nuevo, y el que deja se conserva mientras aún deba allí una relectura o nombre una copia, se dice en cada arranque y en -migrate como owed there, y se recupera si el destino vuelve a apuntar allí. Una URL escrita de otra forma, con una barra al final, una mayúscula o el puerto por omisión, es el mismo almacén. Un fichero de estado borrado tras una actualización se lleva el registro consigo, y los almacenes a los que no se puede preguntar se toman entonces por de la versión en marcha; también se lleva una relectura aún debida, y nada vuelve a leer ese historial hasta que lo haga un -backfill -families de las familias que nombra.

Un cambio hecho antes de la 1.0.0, las etiquetas state y reason de los elementos de alerta, no lo escribió nunca una versión publicada, así que solo puede mostrarlo un almacén al que se le puede preguntar.

La 2.6.0 guarda lo que una pasada aprendió de GitHub en un fichero de caché junto al fichero de estado, y la 2.5.x no escribía ninguno. Así que el primer arranque no encuentra nada que leer, lo dice en debug como no cache file yet, the first pass of each family pays in full, y lo pregunta todo una vez sin ETag. Es el precio que pagaba cada reinicio de la 2.5.x: medido en el servicio del autor el 2026-09-26, los primeros 38 minutos tras un reinicio gastaron 1.092 peticiones core cobradas en pasadas que costaban unas 66 con la caché caliente. Desde el segundo arranque el fichero está ahí, y el log dice cache file read.

achievements recorre entero el historial de fusiones, una vez

Sección titulada «achievements recorre entero el historial de fusiones, una vez»

El recuento de pull requests en coautoría que hay detrás de Pair Extraordinaire se guarda en el fichero de estado desde la 2.6.0, y un fichero de estado de la 2.5.x no tiene ninguno. La primera pasada de achievements recorre por tanto todas las pull requests que la cuenta ha fusionado: 35 consultas y 23,7 MB sobre 2.315, medido el 2026-09-27. A partir de ahí una pasada recorre los días desde el recuento que guarda, y el historial entero otra vez una vez por semana.

La consulta de pull requests se dimensiona por repositorio a partir de los recuentos que lee totals, y la 2.6.0 guarda esos tamaños en el fichero de caché. La primera pasada no tiene ninguno, así que corre totals antes que las pull requests diga lo que diga su cadencia. Con su cadencia de una hora, totals suele tocar de todos modos después de actualizar, y entonces simplemente corre primero; solo cuando no toca, y la pasada no es la de cebado, que corre todas las familias, el log dice por qué corre:

level=INFO msg="no page sizes remembered, running totals before the pull requests it sizes"

Un fichero de estado de la 2.5.x tiene las familias diarias de la cuenta marcadas en un mismo instante y las de doce horas en otro, porque es cuando corrieron, juntas. La 2.6.0 arranca como mucho una familia de seis horas o más por pasada, así que el primer día tras la actualización las trae una por tic: a lo largo de hasta dos horas y media con las cadencias internas, y más con deps, history o joblogs encendidas. El log nombra quién arranca y quién espera, bajo slow families due together take turns, y desde entonces cada una lleva su propio horario. Ver las familias lentas se turnan.

La búsqueda que hay detrás de gh_account_total.commented_elsewhere contaba también los hilos que la cuenta comentó en sus propios repositorios. Desde la 2.5.2, cuyos cambios salieron en la 2.6.0, los deja fuera, como ya hacían sus dos hermanos, y el campo conserva su nombre. Así que la serie baja en todos los almacenes por la diferencia en la primera pasada de totals tras la actualización, de 125 a 55 en la cuenta en la que se midió. Es una corrección, no una pérdida.

La 2.6.0 añade campos a medidas cuyas tablas creó una versión anterior, y una tabla creada por una versión anterior no tiene columna para ellos. El destino PostgreSQL que conecta lee las columnas de cada tabla la primera vez que su proceso se encuentra con ella y añade las que faltan con ALTER TABLE ... ADD COLUMN IF NOT EXISTS. El destino de fichero SQL no puede preguntar, así que su fichero lleva esa sentencia para cada campo, y reproducirlo en una base de datos que llenó una versión anterior hace que psql imprima un aviso por cada tabla y cada columna que ya existen. Son de esperar:

NOTICE: relation "gh_repo" already exists, skipping
NOTICE: column "stars" of relation "gh_repo" already exists, skipping

Ver cómo llegan las declaraciones.

La columna Stars de Work elsewhere espera a outbound

Sección titulada «La columna Stars de Work elsewhere espera a outbound»

La tabla “Work elsewhere” une gh_upstream_repo, una medida que añade la 2.6.0, para las estrellas de cada repositorio. Hasta que la primera pasada de outbound de la versión nueva la escribe, que es dentro de la hora, InfluxDB y PostgreSQL rechazan la tabla entera en vez de dejar vacía la columna, y un rango que termina antes de la actualización no tiene estrellas que mostrar en ningún almacén. Espera a esa pasada, o publica los dashboards después de ella; ver los datos parecen mal.

Una configuración copiada de un ejemplo antiguo conserva las cadencias viejas

Sección titulada «Una configuración copiada de un ejemplo antiguo conserva las cadencias viejas»

Hasta la 2.6.0 la configuración de ejemplo fijaba cada familia bajo every.families al valor interno de su versión, así que un config.yaml copiado de ella las fija todas. Uno copiado de la 2.5.x mantiene doce más lentas de lo que las corre la 2.6.0: account, outbound y totals a 12h, achievements a 24h, stars, billing y analyses a 6h, discussions a 2h, deployments a 1h, y activity, events y notifs a 30m. Nada avisa, porque el aviso es para una cadencia cuatro veces más rápida que la interna. Borrar esas líneas es lo que recoge los valores actuales; desde la 2.6.1 el ejemplo las muestra comentadas, así que una copia suya no fija ninguna. Ver cada familia, su grupo y su cadencia interna.

Si un comentario es la respuesta aceptada es un campo

Sección titulada «Si un comentario es la respuesta aceptada es un campo»

gh_discussion_comment llevaba is_answer como etiqueta, y quien mantiene un repositorio acepta una respuesta días después de escribirse el comentario, así que un comentario leído antes y después de eso eran dos filas en el mismo instante. La 2.6.1 no escribe ningún is_answer: el campo answers que ya llevaba cada fila, 1 para la respuesta aceptada y 0 para cualquier otro comentario, dice lo mismo. Un almacén escrito antes de la 2.6.1 y después tiene la medida con dos formas hasta que se borra la medida y se vuelve a llenar con un relleno histórico. Los dashboards leen las dos formas, una fila por comentario, y la página de medidas dice qué guarda cada almacén y cómo borrarla. -migrate dice cuáles de los almacenes configurados guardan todavía la forma antigua, bajo 2.6.1/gh_discussion_comment/is_answer: ver Migraciones.

Lo que la forma antigua todavía le cuesta a quien lee es una respuesta aceptada y retirada después: su fila antigua dice aceptada, así que los dos paneles de comentarios la leen aceptada hasta que el almacén se pone al día. Medido en la batería en contenedores con una respuesta retirada en el GitHub falso, en InfluxDB 3.11.2, PostgreSQL 18.6, Elasticsearch 9.5.3, Graphite 1.1.10-5 y el fichero SQL reproducido en PostgreSQL: Answers elsewhere y Discussion answers la leen aceptada, una fila para el comentario, antes de actualizar en todos los almacenes; no aceptada, todavía una fila, en los tres primeros tras un arranque con migrate: auto, que deja Graphite y el fichero SQL a quien los lleva; y no aceptada en los cinco tras -migrate -yes, una vez ejecutadas las órdenes de Graphite y reproducido el fichero desde donde estaba.

state_file, sinks.dedupe_file, log.file, sinks.file.path y sinks.sql.path toman una ~ inicial como el directorio personal y un ${VAR} del entorno, como siempre hicieron las credenciales y las direcciones. Una configuración que escribía cualquiera de los dos obtenía un directorio llamado con esos caracteres, dentro del directorio de trabajo, y ahora obtiene la ruta que quería decir. Donde eso era el fichero de estado, el estado que guardaba la versión anterior está en el directorio del nombre raro, y la nueva arranca sin él: mueve los ficheros antes del primer arranque si los recorridos que ahorra merecen conservarse. Un ${VAR} en una ruta que no está definido o está vacío detiene el arranque y nombra la clave, en vez de dejar la ruta sin esa parte. Ver expansión de ${VAR}.

Un volumen de estado de Docker no necesita chown

Sección titulada «Un volumen de estado de Docker no necesita chown»

Hasta la 2.6.0 la imagen no tenía /var/lib/ghchronicle, así que el volumen que una pila de compose o un docker run montaba ahí se creaba como propiedad de root, y el colector, uid 65532, no guardaba en él ni su estado ni su caché hasta que se le entregaba el volumen con un chown. Desde la 2.6.1 la imagen trae el directorio, propiedad del uid 65532, y Docker le da ese dueño a un volumen nuevo montado ahí. Un volumen vacío que una imagen anterior dejó a root se entrega del mismo modo la primera vez que se crea sobre él un contenedor de la 2.6.1, que es lo que hacen docker compose pull y después docker compose up -d; uno ya entregado se queda como está. Un directorio del anfitrión montado ahí sigue necesitando su chown. Ver qué tiene que ser escribible.

achievements recorre entero el historial de fusiones otra vez

Sección titulada «achievements recorre entero el historial de fusiones otra vez»

El recuento de coautorías que hay detrás de Pair Extraordinaire lee ahora todos los commits de una pull request que tiene más de cien, donde la 2.6.0 leía los cien primeros y contaba el resto como un mínimo. Eso cambia la regla con la que se guarda el recuento, así que el recuento que tiene un fichero de estado de la 2.6.0 se deja a un lado y la primera pasada de achievements tras la actualización recorre todas las pull requests que la cuenta ha fusionado: 41 consultas con la de cuentas, 41 puntos, en 1 minuto y 53 segundos sobre la cuenta medida, el 2026-09-28. Un aviso co-authored pull request count is a floor que volvía en cada pasada deja de salir con ello, salvo que de verdad no se pudieran leer los commits que le quedaban a una pull request. Ver gh_achievement_progress.