Saps què va passar a les tres de la matinada: quinze db_timeout amb les 200 connexions esgotades. El que no saps és per què. I ara la Marta hi afegeix llenya: «Diversos comercials diuen que el web va lent al matí, cap a les nou. És cosa nostra?». «Va lent» no és una dada, és una sensació; convertir-la en un número, trobar el recurs culpable i demostrar que el canvi ha servit és justament la feina d'aquesta lliçó. Aprendràs un mètode reproduïble en lloc d'una col·lecció d'ordres soltes, a interpretar de debò el que diuen uptime, free o iostat, i a establir una línia base de srv-tramontana sense la qual cap mesura no significa res.

Contingut

  1. Monitorar, diagnosticar i el mètode USE
  2. CPU: càrrega mitjana, vmstat, mpstat i el steal
  3. Memòria: què significa «usada», intercanvi i l'OOM killer
  4. Disc: iostat -xz, latència enfront de cabal
  5. Xarxa: sar -n DEV, ss -s i les retransmissions
  6. Eines de conjunt i la història amb sar
  7. Mètriques contínues i els quatre golden signals
  8. Procediment per a «el servidor va lent»
  9. Ajustos a l'abast d'un administrador
  10. La línia base de srv-tramontana
  11. Cas Tramontana: «el web va lent al matí»

  1. Monitorar, diagnosticar i el mètode USE

Són dues activitats diferents i es confonen constantment:

  • Monitorar és saber com està el sistema de manera contínua i sense que ningú miri: mètriques cada quinze segons, guardades, amb alertes. Respon a «va bé?» abans que truqui el client.
  • Diagnosticar és esbrinar per què va malament en un moment concret, amb eines interactives i una hipòtesi que es confirma o es descarta.

Un humà mirant top no és monitoratge: és diagnòstic manual, ocasional i sense memòria. Necessites totes dues, i la primera fa possible la segona, perquè una mesura sense punt de comparació no diu res: una càrrega de 3,5 pot ser normal o catastròfica, i només ho saps si coneixes la d'ahir.

El mètode USE (de Brendan Gregg) dona l'ordre en què es mira. Per a cada recurs —CPU, memòria, disc, xarxa— es comproven tres coses:

Dimensió Pregunta En CPU En disc
Utilització Quina part del temps està ocupat? %us + %sy %util d'iostat
Saturació Quanta feina espera a la cua? Columna r de vmstat aqu-sz, await
Errors Hi ha fallades comptabilitzades? Excepcions de màquina Errors d'E/S a dmesg

La seva utilitat pràctica és que evita perdre temps: en cinc minuts recorres els quatre recursos amb tres preguntes cadascun i en surts sabent quin és el coll d'ampolla.

  1. CPU: càrrega mitjana, vmstat, mpstat i el steal

$ uptime ; nproc
 09:14:22 up 6 days,  2:31,  2 users,  load average: 3.42, 2.10, 1.08
2

Els tres números són la mitjana de processos en estat executable (R) o en espera ininterrompible (D) durant 1, 5 i 15 minuts. Dues regles que ho canvien tot. Primera: cal normalitzar pel nombre de nuclis; amb nproc = 2, una càrrega de 3,42 són 1,71 processos per nucli i el sistema està saturat, mentre que el mateix 3,42 en una màquina de 16 nuclis seria un 21 % d'ocupació, és a dir, res. Segona: l'estat D compta, i aquest és el matís que gairebé ningú no coneix, perquè a Linux la càrrega inclou els processos bloquejats esperant disc; per això pots veure una càrrega de 8 amb la CPU al 5 %.

La tendència també informa: 3,42 2,10 1,08 és una càrrega pujant (el problema comença ara); 1,08 2,10 3,42 és una que ja s'està resolent.

vmstat 1, columna a columna

$ vmstat 1 5
 r  b   swpd    free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 4  2      0  198432  91240 1842104    0    0    12    48  412  980 18  4 22 56  0
 5  3      0  196108  91240 1843320    0    0     8 14620  902 2140 21  6  9 64  0
 4  3      0  195884  91240 1843644    0    0     4 15108  918 2205 19  5  8 68  0
Columna Significat Quan preocupa
r Processos llestos per executar, esperant CPU Si supera de manera sostinguda el nre. de nuclis
b Processos bloquejats en E/S (estat D) Qualsevol valor sostingut > 0 apunta al disc
si / so KiB/s entrant i sortint de l'intercanvi Qualsevol valor sostingut és dolent: thrashing
bi / bo Blocs llegits/escrits per segon Context per al disc
us / sy / id % de CPU en usuari, nucli i ociós sy alt: crides al sistema o xarxa
wa % esperant E/S Alt amb id baix: el disc és el coll
st % robat per l'hipervisor (steal) > 5 % sostingut: el problema no és a la teva VM

La primera línia de vmstat és la mitjana des de l'arrencada: ignora-la sempre i mira de la segona endavant. A l'exemple, wa en 56–68 % amb r en 4–5 i bo disparat diu a crits que el coll d'ampolla és el disc, no la CPU.

L'st mereix un apunt: en una VM és temps que l'hipervisor va donar a una altra màquina, així que un st del 20 % significa que cap optimització teva no arreglarà res, perquè el problema és a l'amfitrió o al proveïdor.

I el desglossament per nucli i per procés:

$ mpstat -P ALL 1 1 | tail -3
Average:  CPU  %usr %nice %sys %iowait %steal %idle
Average:    0  19.2   0.0  4.8    58.1    0.0   17.5
Average:    1  17.9   0.0  5.1    54.3    0.0   22.4
$ pidstat -u 1 1 | sort -k8 -rn | head -3
12:31:03  UID  PID  %usr %system  %wait  %CPU  CPU  Command
12:31:03  997 1284  16.00    3.00   1.00 19.00    0  tramontana
12:31:03 1000 8842   4.00    9.00  22.00 13.00    1  copia_tramontan

mpstat -P ALL revela un cas molt comú: la mitjana global sembla raonable però un sol nucli està al 100 % perquè l'aplicació no paral·lelitza. pidstat reparteix el consum per procés, i la seva columna %wait —temps esperant que li donin CPU— és or pur per detectar contenció.

  1. Memòria: què significa «usada», intercanvi i l'OOM killer

$ free -h
               total        used        free      shared  buff/cache   available
Mem:           3.8Gi       1.1Gi       208Mi        18Mi       2.5Gi       2.4Gi
Swap:          2.0Gi          0B       2.0Gi

«Lliure: 208 Mi» no és un problema. És exactament el contrari: la RAM lliure és RAM desaprofitada, i el nucli la fa servir com a memòria cau de pàgina per no haver de tornar a llegir del disc. Les columnes que importen:

used és la memòria de processos sense memòria cau ni memòries intermèdies; buff/cache és memòria cau de pàgina i metadades, que el nucli allibera a l'instant si cal; i available és la xifra que cal mirar: quanta memòria pot obtenir una aplicació nova sense fer intercanvi. Amb 2,4 GiB disponibles de 3,8, srv-tramontana va sobrat; l'alarma seria available caient cap a zero, no free.

$ grep -E 'MemTotal|MemAvailable|Dirty' /proc/meminfo   # el detall cru; vmstat -s resumeix
$ ps -eo pid,user,rss,vsz,comm --sort=-rss | head -3
   PID USER       RSS      VSZ COMMAND
  1284 svc-tram 219848  1284932 tramontana
  1102 postgres  98204   412088 postgres

Tres xifres que es confonen a diari: VSZ és tot l'espai d'adreces reservat —biblioteques compartides i memòria demanada però mai tocada incloses—, gairebé sempre enorme i irrellevant; RSS són les pàgines realment a la RAM, útil però compta sencera cada biblioteca compartida a cada procés, així que sumar els RSS dona molt més que la RAM total; i PSS reparteix cada pàgina compartida entre els qui la fan servir, i és l'única que suma bé (es veu amb smem -k o a /proc/PID/smaps_rollup).

Intercanvi i thrashing

Tenir intercanvi ocupat no és dolent per si sol: el nucli descarrega pàgines que ningú no toca. El greu és el tràfec constant, que es veu a si/so de vmstat. Si aquelles columnes estan actives de manera sostinguda, el sistema passa més temps movent pàgines que treballant: això és thrashing, i es percep com una lentitud brutal amb la CPU gairebé ociosa.

L'OOM killer

Quan no queda memòria ni intercanvi, el nucli tria una víctima i la mata. Saber que ha actuat és fonamental, perquè el símptoma que arriba és «el servei s'ha reiniciat sol»:

$ sudo journalctl -k --since yesterday --grep -i 'out of memory'
Aug 17 04:41:07 srv-tramontana kernel: Out of memory: Killed process 1284 (tramontana)
    total-vm:1284932kB, anon-rss:2894120kB, oom_score_adj:0

Tria per oom_score, que premia matar el procés que més memòria allibera, ponderat per oom_score_adj (de −1000 a 1000). Es consulta a /proc/PID/oom_score i s'ajusta en calent amb sudo choom -p 1284 -n -500. Encara que en un servei de systemd el correcte és declarar-ho a la unitat (OOMScoreAdjust=-500) i, sobretot, posar MemoryMax com vas veure a 05-05: així l'OOM actua dins del cgroup del servei i no s'endú per davant la base de dades.

  1. Disc: iostat -xz, latència enfront de cabal

$ iostat -xz 1 2 | tail -4
Device   r/s     rkB/s   w/s     wkB/s   rareq-sz wareq-sz aqu-sz  r_await w_await %util
dm-0     2.00     8.00 148.00 14620.00     4.00    98.78    3.42     1.20   22.85  97.60
sda      1.00     4.00  92.00 15108.00     4.00   164.22    2.98     0.90   31.10  94.20
Columna Què mesura Llindar orientatiu
%util % de temps amb almenys una petició en vol > 90 % sostingut: saturat (menys fiable en SSD/NVMe)
r_await / w_await Latència mitjana per petició, en ms > 10 ms en SSD o > 20 ms en disc mecànic: hi ha cua
aqu-sz Profunditat mitjana de la cua > 1 sostingut: hi ha saturació

La distinció crítica és latència enfront de cabal: un disc pot moure 200 MB/s tan tranquil amb una tasca seqüencial (cabal alt, latència baixa) i ofegar-se amb 5 MB/s d'escriptures aleatòries petites (cabal ridícul, latència terrible). A l'usuari li fa mal la latència, no el cabal.

I qui està escrivint:

$ sudo iotop -b -n 1 -o -P | head -3
  PID  PRIO  USER   DISK READ  DISK WRITE  COMMAND
 8842  idle  operad   0.00 B/s   13.94 M/s  copia_tramontana.sh
$ sudo lsof -p 8842 | grep -E 'REG.*backups' | head -1
copia_tra 8842 operador  4w  REG  253,0  /srv/.../tramontana-2026-08-18.tar.gz.parcial

  1. Xarxa: sar -n DEV, ss -s i les retransmissions

$ sar -n DEV 1 1 | grep -E 'IFACE|enp0s3'
12:44:01     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s
12:44:02    enp0s3    412.00    398.00    118.42    902.18
$ ss -s | head -2
Total: 214
TCP:   187 (estab 142, closed 21, orphaned 0, timewait 19)
$ ss -tn state established '( dport = :5432 )' | wc -l
200

Aquella última ordre és un avançament del cas d'avui: dues-centes connexions establertes contra el port de la base de dades, exactament el max_connexions d'app.conf.

Per veure el trànsit en directe, nload (per interfície) o iftop (per conversa) són immediats.

I l'indicador de salut de TCP que cal conèixer, nstat -az | grep TcpRetransSegs: les retransmissions són segments que es van haver de reenviar perquè no va arribar confirmació. Un percentatge petit és normal; una taxa creixent indica pèrdua de paquets —cable, saturació d'un enllaç o un dispositiu intermedi descartant trànsit—. El diagnòstic complet de xarxa, amb mtr i les capes, ja el tens de 03-08.

  1. Eines de conjunt i la història amb sar

Eina Aporta
htop top navegable: arbre amb F5, filtres, nice interactiu, barres per nucli
atop Guarda història cada 10 min i permet «rebobinar» a l'hora de l'incident
glances / dstat Tauler únic amb alertes de llindar / sèries per segon, ideals per a CSV
sysstat / sar La memòria del rendiment: mètriques històriques cada 10 minuts

El punt que més vegades es passa per alt: la foto d'ara no serveix sense la d'ahir. Si la Marta es queixa a les 09:10 d'alguna cosa que va passar a les 09:00, top ja no diu res; sar sí:

sudo apt install sysstat
sudo sed -i.bak-$(date +%F) 's/^ENABLED="false"/ENABLED="true"/' /etc/default/sysstat
sudo systemctl enable --now sysstat sysstat-collect.timer
sar -u -s 08:50:00 -e 09:30:00   # CPU en aquella franja d'AVUI; -q dona la càrrega històrica
sar -r -f /var/log/sysstat/sa17  # memòria del dia 17
sar -b -s 04:00:00 -e 05:00:00   # E/S durant la còpia nocturna

Activar sysstat costa un minut i és el que converteix «em sembla que anava lent» en «a les 09:04 el %iowait va pujar al 61 %».

  1. Mètriques contínues i els quatre golden signals

Per a més d'un servidor, o per alertar sense que ningú miri, l'estàndard d'avui és Prometheus (base de dades temporal que consulta els objectius), node_exporter (exposa les mètriques del sistema a /metrics), Grafana (taulers) i Alertmanager (avisos). No els muntem aquí: és matèria del Mòdul 8. El que sí que t'has d'emportar és què mesurar, els quatre golden signals:

Senyal Què mesura A Tramontana
Latència Durada d'una petició en percentils (p50, p95, p99), separant les que fallen ms d'acces.log
Trànsit / Errors Peticions per segon / taxa de fallades Línies per minut i els 23 codis d'error del registre
Saturació Com de ple està el recurs més limitat connexions_actives / max_connexions

I una regla sobre alertes: una alerta que sona a diari deixa de llegir-se. Alerta sobre símptomes que fan mal a l'usuari (latència p95, taxa d'errors), no sobre cada pic de CPU. És la mateixa disciplina del «silenci si tot va bé» dels teus scripts.

  1. Procediment per a «el servidor va lent»

Aquest és el procediment numerat que pots aplicar tal qual, en aquest ordre, sense saltar-te passos:

  1. Tradueix la queixa a un número mesurable. Quina operació, a quina hora, quant triga ara i quant abans? Sense això no pots saber si has arreglat res.
  2. Foto de 60 segons. uptime, vmstat 1 5, free -h, iostat -xz 1 3, ss -s, systemctl --failed. Amb sis ordres saps si el problema és CPU, memòria, disc o xarxa.
  3. Compara amb la línia base. És anormal, o sempre ha estat així i el que ha canviat és l'expectativa?
  4. Identifica el recurs amb USE i tria'n un, descartant els altres explícitament.
  5. Localitza el culpable dins d'aquell recurs amb pidstat, iotop, ss o top -H: nom i PID.
  6. Formula una hipòtesi falsable. «La còpia de les 04:20 satura el disc i per això les consultes caduquen» es pot confirmar o descartar; «va lent» no.
  7. Revisa què va canviar: journalctl --since, /var/log/apt/history.log, git log dels teus scripts, l'HISTORIAL. El 80 % dels problemes nous vénen d'un canvi recent.
  8. Mesura abans de tocar res i guarda les xifres en un fitxer amb data.
  9. Canvia UNA sola cosa i documenta què i per què.
  10. Mesura després, en les mateixes condicions, i compara. Si no millora, reverteix abans de provar una altra cosa.
  11. Anota el resultat a l'HISTORIAL, fins i tot —sobretot— si el canvi no va servir.

Els passos 8, 9 i 10 són innegociables. Canviar tres paràmetres alhora i veure que millora no t'ensenya res: no saps quin va servir, i arrossegaràs dos ajustos inútils per sempre.

  1. Ajustos a l'abast d'un administrador

Els paràmetres del nucli via sysctl són matèria de 07-03 i el perfilatge amb perf i eBPF és de 07-02. El que sí que és a les teves mans avui:

Límits de fitxers oberts. Un servidor amb moltes connexions esgota el límit per procés i rebutja peticions amb Too many open files:

$ ulimit -n ; cat /proc/1284/limits | grep 'open files'
1024
Max open files            1024                 4096                 files

En un servei de systemd no es toca /etc/security/limits.conf —que només s'aplica a sessions d'accés via PAM—, sinó la unitat:

[Service]
LimitNOFILE=65535

Límits de recursos del servei: MemoryMax i CPUQuota de 05-05, que a més de protegir serveixen per mesurar, perquè systemd-cgtop mostra si el servei arriba al sostre. I noatime a fstab (05-04), que evita una escriptura per cada lectura i es nota en un servidor amb molts fitxers petits.

Perfilatge somer de fils: top -H -p 1284 desglossa el consum fil a fil quan un procés multifil va carregat i no saps quina part. perf top donaria el desglossament per funció, però això és 07-02.

Els paràmetres de l'aplicació mateixa, que solen rendir més que qualsevol ajust del sistema: a Tramontana, max_connexions i timeout_consulta d'/etc/tramontana/app.conf.

  1. La línia base de srv-tramontana

Una línia base és una foto del comportament normal, presa quan tot va bé, per comparar quan no. Es guarda al costat de la de referència del Mòdul 1:

#!/usr/bin/env bash
# /home/operador/scripts/linia_base.sh — foto de rendiment amb data
set -euo pipefail
desti="/srv/tramontana/backups/liniabase-$(date +%F-%H%M).txt"
{
    echo "== $(date --iso-8601=seconds) $(hostname) =="
    uptime; nproc; free -h
    vmstat 1 5 | tail -4
    iostat -xz 1 2 | tail -6
    ss -s; df -h /; df -i / | tail -1
} > "$desti"

Valors normals mesurats a srv-tramontana un dimarts a les 11:00, amb l'aplicació en marxa:

Mètrica Valor normal Llindar d'atenció
Càrrega mitjana (2 vCPU) 0,15 – 0,40 > 2,0 sostingut
CPU id / wa 85 – 95 % / 0 – 3 % < 40 % / > 20 %
Memòria disponible 2,3 – 2,5 GiB < 400 MiB
si/so d'intercanvi 0 Qualsevol valor sostingut
w_await a dm-0 0,8 – 2,5 ms > 20 ms
Connexions a 5432 / disc / 30 – 60 / 30 % > 150 / > 85 %

Aquella taula, i no la intuïció, és el que converteix una mesura en un diagnòstic.

  1. Cas Tramontana: «el web va lent al matí»

Pas 1 — Traduir la queixa. Preguntem i mesurem: la cerca de disponibilitat, que normalment respon en 180 ms, triga entre 4 i 9 segons entre les 08:50 i les 09:15. Ja és un número.

Pas 2-3 — Foto i comparació amb la línia base. Com que l'incident és recurrent, mesurem a les 09:00 de l'endemà:

$ uptime
 09:04:11 up 6 days, 22:20,  2 users,  load average: 3.42, 2.10, 1.08
$ vmstat 1 3 | tail -1
 5  3      0  195884  91240 1843644    0    0     4 15108  918 2205 19  5  8 68  0

Càrrega 3,42 amb 2 vCPU (línia base: 0,15–0,40) i wa al 68 % (base: 0–3 %) amb id al 8 %. No falta CPU: falta disc. Memòria i intercanvi, normals. Recurs identificat: E/S.

Pas 4-5 — El culpable.

$ iostat -xz 1 2 | tail -2
Device   r/s   rkB/s    w/s    wkB/s  aqu-sz  w_await  %util
dm-0    2.00    8.00 148.00 14620.00    3.42    22.85   97.60
$ sudo iotop -b -n 1 -o | tail -1
 8842  idle operador   13.94 M/s  copia_tramontana.sh
$ journalctl -u tramontana-copia.service --since "2 days ago" -o short-iso | grep -E 'inici|completada'
2026-08-17T04:20:06+0200 backup[8811]: inici de còpia (versio=3.2.1)
2026-08-17T06:02:44+0200 backup[8811]: còpia completada en 6158s
2026-08-18T04:20:07+0200 backup[8842]: inici de còpia (versio=3.2.1)

w_await de 22,85 ms davant dels 0,8–2,5 de la base, %util al 97,6 %, i qui escriu és la còpia de seguretat, que en teoria es llança a les 04:20: la del dia 17 va trigar 1 h 42 min i la del 18 encara no havia acabat a les 09:04. El conjunt de dades ha crescut i la còpia se solapa amb l'hora punta.

Pas 6 — Hipòtesi falsable. «La còpia de seguretat satura l'E/S del disc fins passades les 09:00; això allarga les consultes a la base de dades, que arriben al timeout_consulta de 30 s i esgoten les 200 connexions de max_connexions, que és el que provoca els db_timeout dels registres.»

Comprovació de la segona meitat:

$ ss -tn state established '( dport = :5432 )' | wc -l   # 200: el sostre exacte
$ journalctl -u tramontana.service --since "09:00" -p err --no-pager | wc -l
11

Dues-centes connexions exactes —el sostre— i onze errors en quatre minuts. Hipòtesi confirmada: el mateix mecanisme que va causar els db_timeout de les 03:00 de la lliçó anterior.

Pas 7-9 — Què va canviar, mesurar i canviar UNA cosa. L'HISTORIAL ho diu: el volum de còpies es va migrar el 18 i el conjunt de dades ha crescut. La causa arrel és la durada de la còpia, no les connexions. El canvi mínim i reversible:

### /etc/systemd/system/tramontana-copia.service.d/override.conf
[Service]
# La còpia ha d'acabar abans de l'hora punta (08:45); si no, s'avorta i avisa.
RuntimeMaxSec=3h
IOWeight=10
$ sudo systemctl edit tramontana-copia.timer   # OnCalendar=*-*-* 02:30:00
$ sudo systemctl daemon-reload && systemctl list-timers tramontana-copia.timer | tail -1
Wed 2026-08-19 02:30:00 CEST 14h left  tramontana-copia.timer

Pas 10 — Mesurar després, a la mateixa hora i amb les mateixes ordres.

Mètrica a les 09:04 Abans Després
Càrrega mitjana / CPU wa 3,42 / 68 % 0,38 / 2 %
w_await dm-0 22,85 ms 1,40 ms
Connexions a 5432 200 (sostre) 47
Errors db_timeout (09:00–09:15) 11 0
Latència de cerca 4–9 s 190 ms

Pas 11 — Documentar. I l'informe per a la Marta, amb l'estructura de sempre: «La lentitud dels matins la causava la còpia de seguretat, que havia crescut fins a trigar més de quatre hores i continuava escrivint en hora punta; en saturar el disc, les consultes caducaven i s'esgotaven les 200 connexions a la base de dades. Hem avançat la còpia a les 02:30 i li hem posat un límit de 3 hores i menor prioritat d'E/S. Mesurat a les 09:04: la cerca torna a 190 ms i no hi ha errors. Què protegeix això: que la còpia interfereixi amb l'horari laboral. Què no protegeix: si el conjunt de dades continua creixent, hi tornarem a xocar; cal passar a còpies incrementals, i això ho abordem ara mateix. Tampoc no resol que 200 connexions sigui un límit ajustat si creix el nombre d'usuaris.»

sudo tee -a /opt/tramontana/HISTORIAL >/dev/null <<'FI'
2026-08-19  Rendiment matinal (operador)
  - Causa: còpia de 4h+ saturant E/S (w_await 22,85 ms, %util 97,6) passades les 09:00
  - Efecte: consultes a 30s de temps límit -> 200/200 connexions -> db_timeout
  - Canvi: timer a les 02:30, RuntimeMaxSec=3h, IOWeight=10 (un sol canvi, mesurat)
  - Resultat 09:04: càrrega 0,38 / wa 2% / w_await 1,40ms / 47 connexions / 0 errors / 190 ms
  - Pendent: còpies incrementals (la còpia completa continuarà creixent)
FI

Errors Comuns i Consells

  • Llegir la càrrega mitjana sense dividir per nproc. Un 3,42 no significa res fins que no saps quants nuclis hi ha.
  • Espantar-se per «poca memòria lliure». La xifra que importa és available; la memòria cau és memòria ben emprada.
  • Fiar-se de la primera línia de vmstat o iostat. És la mitjana des de l'arrencada, no el moment actual.
  • Mirar %util en un SSD com si fos un disc mecànic. Amb cues paral·leles, un NVMe pot marcar 100 % i no estar saturat. Mira await i aqu-sz.
  • Diagnosticar sense línia base. Sense saber què és normal, qualsevol número sembla alarmant o tranquil·litzador segons l'ànim. I no canviïs diverses coses alhora: no sabràs quina va funcionar, i arrossegaràs ajustos inútils durant anys.
  • No tenir història. Instal·la sysstat el primer dia: quan algú pregunti per les 09:00, ja serà tard per activar-lo.
  • Confondre un símptoma amb la causa. Les 200 connexions eren el símptoma; la còpia era la causa. Pujar max_connexions hauria amagat el problema.
  • Consell: guarda cada mesura en un fitxer amb data, al costat de l'HISTORIAL. D'aquí a sis mesos, aquella carpeta valdrà més que la teva memòria.

Exercicis

  1. Llegir una foto. Un servidor amb 4 vCPU mostra load average: 7,80, 7,20, 6,90, vmstat amb us=6 sy=3 id=4 wa=87 st=0, r=1, b=6, i free -h amb 5,1 GiB disponibles de 8. Quin és el recurs saturat, quin no ho és, i quines són les dues ordres següents?
  2. Un servei que mor de matinada. tramontana.service apareix reiniciat cada nit cap a les 03:40 sense que ningú el toqui. Dona les ordres per confirmar si va ser l'OOM killer i, si ho va ser, dues maneres d'evitar que s'endugui per davant la base de dades.
  3. Demostrar una millora. Dissenya el protocol exacte —ordres, moments i criteri d'èxit— per demostrar que activar noatime a /srv/tramontana/backups escurça la còpia nocturna, de manera que el resultat convenci algú escèptic.

Solucions

1. El recurs saturat és el disc. La prova: wa=87 % amb id=4 % significa que la CPU està aturada esperant E/S, i b=6 són sis processos bloquejats en estat D, que a més són els que inflen la càrrega fins a 7,80 tot i que només hi ha r=1 esperant CPU. Normalitzat, 7,80 entre 4 nuclis serien 1,95, però aquell número és enganyós aquí precisament perquè el componen processos en D, no en R. El que no està saturat: la CPU (us+sy = 9 %) ni la memòria (5,1 GiB disponibles de 8, sense intercanvi en moviment). Les dues ordres següents:

iostat -xz 1 3          # quin dispositiu, amb quina latència (w_await) i quina cua (aqu-sz)
sudo iotop -b -n 1 -o   # quin procés concret està fent aquella E/S

2.

$ sudo journalctl -k --since "03:00" --until "04:00" --grep -i 'out of memory'
Aug 17 03:41:12 srv-tramontana kernel: Out of memory: Killed process 1284 (tramontana)
$ systemctl show tramontana.service -p NRestarts     # NRestarts=6
$ journalctl -u tramontana.service --since "03:00" | grep 'Main process'
Aug 17 03:41:12 systemd[1]: tramontana.service: Main process exited, code=killed, status=9/KILL

status=9/KILL sense que ningú hagi executat un kill és la signatura de l'OOM killer, i el missatge del nucli ho confirma. Fixa't en la coincidència horària amb la còpia nocturna: la memòria cau de pàgina que genera la còpia pressiona la memòria disponible.

Dues maneres de protegir la base de dades:

# (a) A tramontana.service: l'OOM actua DINS del cgroup del servei
[Service]
MemoryMax=512M
Restart=on-failure
# (b) A postgresql.service: fer-la víctima improbable
[Service]
OOMScoreAdjust=-800

La primera és la bona, perquè acota el problema al seu origen: quan Tramontana es passi de memòria morirà Tramontana, i systemd l'aixecarà, sense que el nucli triï víctima a tota la màquina. La segona és un complement defensiu: esbiaixa l'elecció, però no impedeix que la màquina es quedi sense memòria.

3. El protocol, que és el mètode de la secció 8 aplicat:

# 1. Mesurar l'estat actual, tres nits seguides per tenir variabilitat
journalctl -u tramontana-copia.service --since "3 days ago" -o cat | grep 'completada en'
# -> 6158s, 5904s, 6021s  (mediana 6021 s); sar -b -f /var/log/sysstat/sa17 per a l'E/S

# 2. Canviar UNA sola cosa, amb còpia prèvia i verificació
sudo cp -a /etc/fstab /etc/fstab.bak-$(date +%F)
sudo sed -i 's|\(/srv/tramontana/backups.*defaults\)|\1,noatime|' /etc/fstab
sudo diff -u /etc/fstab.bak-$(date +%F) /etc/fstab
sudo mount -o remount /srv/tramontana/backups
findmnt -no OPTIONS /srv/tramontana/backups    # comprovar que noatime està actiu

# 3. Mesurar tres nits més, mateixes ordres i mateix horari
journalctl -u tramontana-copia.service --since "3 days ago" -o cat | grep 'completada en'

Criteri d'èxit, fixat abans de mesurar: reducció de la mediana de durada superior al 10 % sense augment d'errors a journalctl -u tramontana-copia.service -p err. Tres nits a cada costat perquè una sola mesura no distingeix una millora d'una nit fluixa. I si no es compleix el criteri, es reverteix amb el .bak i s'anota a l'HISTORIAL que no va servir: un experiment negatiu documentat estalvia que algú el repeteixi d'aquí a un any.

Conclusió

Ja no depens que algú «noti» que el servidor va lent. Distingeixes monitorar de diagnosticar i apliques el mètode USE —utilització, saturació, errors— als quatre recursos. Llegeixes la càrrega mitjana normalitzada per nproc sabent que inclou els processos en estat D, i interpretes vmstat 1 columna a columna: r i b, si/so, us/sy/id/wa i el st que delata l'hipervisor. Reparteixes el consum amb mpstat -P ALL i pidstat.

En memòria saps que «lliure» és una xifra enganyosa i que la bona és available, distingeixes VSZ, RSS i PSS, reconeixes el thrashing a si/so, i saps demostrar que va actuar l'OOM killer amb journalctl -k i com evitar que s'endugui el veí amb MemoryMax i OOMScoreAdjust. En disc manegues iostat -xz amb %util, await i aqu-sz, tens clara la diferència entre latència i cabal, i localitzes el culpable amb iotop i lsof. En xarxa fas servir sar -n DEV, ss -s i les retransmissions. Coneixes htop, atop, glances i dstat, i —el més important— has activat sysstat per tenir la història sense la qual la foto d'avui no significa res. Saps què són els quatre golden signals i per què una alerta que sona a diari deixa de llegir-se.

Tens un procediment d'onze passos per a «el servidor va lent», amb les tres regles innegociables: mesurar abans, canviar una sola cosa, mesurar després. Tens una línia base de srv-tramontana amb llindars escrits. I has resolt el cas: la lentitud matinal era la còpia de seguretat saturant l'E/S fins passades les 09:00, provocant els db_timeout i l'esgotament de les 200 connexions; avançar-la i limitar-la va tornar la cerca de 4–9 s a 190 ms, amb les xifres d'abans i després escrites a l'HISTORIAL.

Però l'informe per a la Marta acabava amb un cap solt que no pot esperar: la còpia completa continuarà creixent, i amb ella el problema. I hi ha una cosa molt pitjor que ningú no ha comprovat encara: ningú no ha restaurat mai aquella còpia. A Còpies de Seguretat i Restauració, l'última lliçó del mòdul, veuràs per què no existeixen les còpies de seguretat sinó només les restauracions provades: fixaràs RPO i RTO per a Tramontana, aplicaràs la regla 3-2-1 i la retenció per generacions, resoldràs la coherència amb instantànies LVM de 05-04, faràs servir tar --listed-incremental, rsync --link-dest i una eina moderna amb deduplicació i xifratge, i escriuràs el procediment de restauració pas a pas per als tres escenaris que et poden passar de debò.

Curs de Linux: De Principiant a Administrador de Sistemes

Mòdul 1: Introducció a Linux

Mòdul 2: Comandes Bàsiques de Linux

Mòdul 3: Habilitats Avançades en la Línia de Comandes

Mòdul 4: Scripting en Shell

Mòdul 5: Administració del Sistema

Mòdul 6: Xarxes i Seguretat

Mòdul 7: Temes Avançats

Mòdul 8: Projectes Pràctics

© Copyright 2026. Tots els drets reservats