SDP-Cheat-Sheet.md #1

  • //
  • guest/
  • russell_jackson/
  • sdp/
  • doc/
  • SDP-Cheat-Sheet.md
  • Markdown
  • View
  • Commits
  • Open Download .zip Download (9 KB)

SDP Cheat Sheet

Single-page operational reference for the SDP-managed Perforce estate. Aimed at the operator who's been paged at 2 AM and needs to find the right command fast. Companion to the full SDP_Guide.Unix.html and the failover doc DR-Failover-steps-Unix-standby.md in this directory.

Paths (the SDP layout, abbreviated)

/p4/<inst>/                         # per-instance dir (typically <inst> = "1")
  ├── bin/        ->  /p4logs/p4/<inst>/bin            # per-instance binaries
  ├── root/       ->  /p4root/p4/<inst>/db1            # online db.* files
  ├── offline_db/ ->  /p4logs/p4/<inst>/db2            # offline db copy for checkpoints
  ├── logs/       ->  /p4journal/p4/<inst>/logs        # log + journal
  ├── checkpoints/->  /p4checkpoints                   # rotated checkpoints
  ├── depots/     ->  /p4depot/p4/<inst>/depots        # archive content
  ├── tmp/        ->  /p4logs/p4/<inst>/tmp
  ├── .p4tickets
  └── .p4trust

/p4/common/                         # shared across all instances on a host
  ├── bin/        ->  /p4depot/p4/common/bin           # SDP scripts + p4 binaries
  └── config/                                          # passwd files, mkdirs.cfg, etc.

/p4/ssl/                            # certificate.txt, privatekey.txt, config.txt
/p4/sdp/                            # vendored SDP source tree (synced from repo)

Environment (always do this first)

sudo -i -u perforce
source /p4/common/bin/p4_vars 1     # <inst>; populates P4PORT, P4USER, P4TICKETS, etc.

Useful exports after sourcing:

Var Typical value Notes
P4HOME /p4/<inst> base
P4PORT <host>:1666 local p4d
P4MASTERPORT <commit>:1666 upstream commit master
P4USER p4admin default admin
P4TICKETS /p4/<inst>/.p4tickets per-instance, NOT ~/.p4tickets
P4TRUST /p4/<inst>/.p4trust for SSL fingerprints
P4SERVICEUSER svc_<replica-id> service account on master
P4REPLICA TRUE / empty TRUE on standbys / replicas / edges

Service control

systemctl status   p4d_1                     # p4d
systemctl status   p4broker_1                # broker (where present)
systemctl status   p4p_<name>                # proxy (one per p4p instance)
systemctl status   p4prometheus              # metrics exporter
journalctl -u p4d_1 -e                       # log tail

The init scripts at /p4/<inst>/bin/p4d_<inst>_init {start|stop|restart|status} are what the systemd units wrap.

Replication health (run as perforce)

p4 pull -lj                          # journal+statefile state vs master
p4 pull -ls                          # file-transfer summary (active/total)
p4 pull -l --filter=failed           # only failed transfers (sticky retries)
p4 servers -J                        # all servers + their last-known journal pos
p4 monitor show -ae                  # active commands incl. background pulls
p4 -ztag info | grep -E "version|server"

Output format note (post-2025.1): p4 pull -lj says capital Journal / Sequence. Older parsers grepping lowercase miss every match.

Daily / weekly ops

/p4/common/bin/daily_checkpoint.sh 1            # rotate journal + checkpoint
/p4/common/bin/weekly_checkpoint.sh 1
/p4/common/bin/p4verify.sh 1                    # archive integrity
/p4/common/bin/recreate_db_checkpoint.sh 1      # rebuild offline db from latest
/p4/common/bin/sync_replica.sh 1                # rsync from master (replica only)
/p4/common/bin/recover_replica.sh 1             # full replica DB recover
/p4/common/bin/recover_edge.sh 1                # edge-server variant
/p4/common/bin/recover_standby_db.sh 1          # standby variant
/p4/common/bin/live_checkpoint.sh 1             # snapshot without stopping p4d

Failover / standby promotion (high-stakes)

/p4/common/bin/convert_standby_to_master.sh 1
/p4/common/bin/convert_old_master_to_standby.sh 1

Reference: sdp/doc/DR-Failover-steps-Unix-standby.md for the full procedure.

Configuration

p4 configure show                          # everything
p4 configure show <serverid>               # per-server
p4 configure set <serverid>#<name>=<val>
p4 configure unset <serverid>#<name>

# Replica startup (typical)
p4 configure set <replica-id>#startup.1='journalcopy -i 0'
p4 configure set <replica-id>#startup.2='pull -L -i 0'
p4 configure set <replica-id>#startup.3='pull -u -i 1'

License + SSL

File Path Source
License /p4/<inst>/root/license Perforce Support
p4d cert /p4/ssl/certificate.txt autogen via p4d -Gc reading /p4/ssl/config.txt, or pre-baked
p4d key /p4/ssl/privatekey.txt same
Broker cert/key /p4/ssl/certificate.txt / privatekey.txt typically per-cluster, sourced from HashiCorp Vault
Trust fingerprint /p4/<inst>/.p4trust populated by first p4 trust -y
p4 -p ssl:<host>:1666 trust -y      # accept fingerprint (per-instance)
p4d -Gc                             # generate self-signed pair from /p4/ssl/config.txt

Cron / queue health

Script When What
daily_checkpoint.sh nightly rotate journal + take checkpoint
weekly_checkpoint.sh weekend full checkpoint + verify
p4login.sh every 4h refresh p4admin ticket
sync_replica.sh nightly rsync archives from master (replicas)

Common gotchas (the real ones, not the manual)

  • /p4/common/bin/p4 is mode 0700 perforce:perforce and lives on NFS with root_squash — root cannot execve it. Anything that runs as root and shells p4 must sudo -u perforce first.
  • P4TICKETS defaults to $HOME/.p4tickets. The SDP convention is per-instance at /p4/<inst>/.p4tickets — only set after source p4_vars. A bare p4 login outside that env writes the wrong ticket file.
  • Forwarding-standbys use journalcopy for the journal + pull for archives. Forwarding-replicas use pull for both. The startup config differs.
  • A negative Sequence_Difference from p4 pull -lj means the replica is "ahead" of what the queried master endpoint reports — almost always means the replica is now talking to a different master than it used to (LB rotation, recent P4TARGET change). Real divergence, not a metric flap.
  • Filenames with bytes that aren't valid UTF-8 (e.g., 0xF1 for ñ from cp1252) won't store on UTF-8-strict shared volumes (Pure, some NFS appliances). Native ext4 / xfs is fine. Fix is p4 move to a clean name — see "Discovery" below.
  • p4 binaries on disk follow p4_<rel>.<bld> symlinked to p4_<inst> — version upgrades swap the symlink, not the binary.

Discovery: find paths with non-UTF-8 bytes

sudo -u perforce p4 verify -m1 //... 2>&1 \
  | grep -P '[\x80-\xff]' \
  | tee /tmp/non-utf8-paths.txt

# OR, walk the depot tree on disk
sudo find /p4/1/depots -name $'*\xf1*' 2>/dev/null

Once the list is in hand, a p4 -c <client> move per file (or batched in a single submit) renames them to UTF-8-clean names. Coordinate with the depot's consumers — Maya / Yeti / etc. scenes referencing the old literal paths will break.

Quick refs (open these first when paged)

  • sdp/doc/SDP_Guide.Unix.html — full SDP guide
  • sdp/doc/DR-Failover-steps-Unix-standby.md — failover procedure
  • /p4/common/bin/ — every script you might need
  • p4 help <command> — beats Googling
  • p4 servers -J — instant view of replica health across the estate
# SDP Cheat Sheet

Single-page operational reference for the SDP-managed Perforce estate. Aimed
at the operator who's been paged at 2 AM and needs to find the right command
fast. Companion to the full `SDP_Guide.Unix.html` and the failover doc
`DR-Failover-steps-Unix-standby.md` in this directory.

## Paths (the SDP layout, abbreviated)

```
/p4/<inst>/                         # per-instance dir (typically <inst> = "1")
  ├── bin/        ->  /p4logs/p4/<inst>/bin            # per-instance binaries
  ├── root/       ->  /p4root/p4/<inst>/db1            # online db.* files
  ├── offline_db/ ->  /p4logs/p4/<inst>/db2            # offline db copy for checkpoints
  ├── logs/       ->  /p4journal/p4/<inst>/logs        # log + journal
  ├── checkpoints/->  /p4checkpoints                   # rotated checkpoints
  ├── depots/     ->  /p4depot/p4/<inst>/depots        # archive content
  ├── tmp/        ->  /p4logs/p4/<inst>/tmp
  ├── .p4tickets
  └── .p4trust

/p4/common/                         # shared across all instances on a host
  ├── bin/        ->  /p4depot/p4/common/bin           # SDP scripts + p4 binaries
  └── config/                                          # passwd files, mkdirs.cfg, etc.

/p4/ssl/                            # certificate.txt, privatekey.txt, config.txt
/p4/sdp/                            # vendored SDP source tree (synced from repo)
```

## Environment (always do this first)

```bash
sudo -i -u perforce
source /p4/common/bin/p4_vars 1     # <inst>; populates P4PORT, P4USER, P4TICKETS, etc.
```

Useful exports after sourcing:

| Var               | Typical value                  | Notes                                  |
|-------------------|--------------------------------|----------------------------------------|
| `P4HOME`          | `/p4/<inst>`                   | base                                   |
| `P4PORT`          | `<host>:1666`                  | local p4d                              |
| `P4MASTERPORT`    | `<commit>:1666`                | upstream commit master                 |
| `P4USER`          | `p4admin`                      | default admin                          |
| `P4TICKETS`       | `/p4/<inst>/.p4tickets`        | per-instance, NOT `~/.p4tickets`       |
| `P4TRUST`         | `/p4/<inst>/.p4trust`          | for SSL fingerprints                   |
| `P4SERVICEUSER`   | `svc_<replica-id>`             | service account on master              |
| `P4REPLICA`       | `TRUE` / empty                 | `TRUE` on standbys / replicas / edges  |

## Service control

```bash
systemctl status   p4d_1                     # p4d
systemctl status   p4broker_1                # broker (where present)
systemctl status   p4p_<name>                # proxy (one per p4p instance)
systemctl status   p4prometheus              # metrics exporter
journalctl -u p4d_1 -e                       # log tail
```

The init scripts at `/p4/<inst>/bin/p4d_<inst>_init {start|stop|restart|status}`
are what the systemd units wrap.

## Replication health (run as perforce)

```bash
p4 pull -lj                          # journal+statefile state vs master
p4 pull -ls                          # file-transfer summary (active/total)
p4 pull -l --filter=failed           # only failed transfers (sticky retries)
p4 servers -J                        # all servers + their last-known journal pos
p4 monitor show -ae                  # active commands incl. background pulls
p4 -ztag info | grep -E "version|server"
```

Output format note (post-2025.1): `p4 pull -lj` says capital `Journal` /
`Sequence`. Older parsers grepping lowercase miss every match.

## Daily / weekly ops

```bash
/p4/common/bin/daily_checkpoint.sh 1            # rotate journal + checkpoint
/p4/common/bin/weekly_checkpoint.sh 1
/p4/common/bin/p4verify.sh 1                    # archive integrity
/p4/common/bin/recreate_db_checkpoint.sh 1      # rebuild offline db from latest
/p4/common/bin/sync_replica.sh 1                # rsync from master (replica only)
/p4/common/bin/recover_replica.sh 1             # full replica DB recover
/p4/common/bin/recover_edge.sh 1                # edge-server variant
/p4/common/bin/recover_standby_db.sh 1          # standby variant
/p4/common/bin/live_checkpoint.sh 1             # snapshot without stopping p4d
```

## Failover / standby promotion (high-stakes)

```bash
/p4/common/bin/convert_standby_to_master.sh 1
/p4/common/bin/convert_old_master_to_standby.sh 1
```

Reference: `sdp/doc/DR-Failover-steps-Unix-standby.md` for the full procedure.

## Configuration

```bash
p4 configure show                          # everything
p4 configure show <serverid>               # per-server
p4 configure set <serverid>#<name>=<val>
p4 configure unset <serverid>#<name>

# Replica startup (typical)
p4 configure set <replica-id>#startup.1='journalcopy -i 0'
p4 configure set <replica-id>#startup.2='pull -L -i 0'
p4 configure set <replica-id>#startup.3='pull -u -i 1'
```

## License + SSL

| File              | Path                                        | Source                                                               |
|-------------------|---------------------------------------------|----------------------------------------------------------------------|
| License           | `/p4/<inst>/root/license`                   | Perforce Support                                                     |
| p4d cert          | `/p4/ssl/certificate.txt`                   | autogen via `p4d -Gc` reading `/p4/ssl/config.txt`, or pre-baked     |
| p4d key           | `/p4/ssl/privatekey.txt`                    | same                                                                 |
| Broker cert/key   | `/p4/ssl/certificate.txt` / `privatekey.txt`| typically per-cluster, sourced from HashiCorp Vault                  |
| Trust fingerprint | `/p4/<inst>/.p4trust`                       | populated by first `p4 trust -y`                                     |

```bash
p4 -p ssl:<host>:1666 trust -y      # accept fingerprint (per-instance)
p4d -Gc                             # generate self-signed pair from /p4/ssl/config.txt
```

## Cron / queue health

| Script                  | When        | What                                          |
|-------------------------|-------------|-----------------------------------------------|
| `daily_checkpoint.sh`   | nightly     | rotate journal + take checkpoint              |
| `weekly_checkpoint.sh`  | weekend     | full checkpoint + verify                      |
| `p4login.sh`            | every 4h    | refresh `p4admin` ticket                      |
| `sync_replica.sh`       | nightly     | rsync archives from master (replicas)         |

## Common gotchas (the real ones, not the manual)

- `/p4/common/bin/p4` is mode `0700 perforce:perforce` and lives on NFS with
  `root_squash` — **root cannot `execve` it**. Anything that runs as root and
  shells `p4` must `sudo -u perforce` first.
- `P4TICKETS` defaults to `$HOME/.p4tickets`. The SDP convention is
  per-instance at `/p4/<inst>/.p4tickets` — only set after `source p4_vars`.
  A bare `p4 login` outside that env writes the wrong ticket file.
- Forwarding-**standbys** use `journalcopy` for the journal + `pull` for
  archives. Forwarding-**replicas** use `pull` for both. The startup config
  differs.
- A negative `Sequence_Difference` from `p4 pull -lj` means the replica is
  "ahead" of what the queried master endpoint reports — almost always means
  the replica is now talking to a different master than it used to (LB
  rotation, recent `P4TARGET` change). Real divergence, not a metric flap.
- Filenames with bytes that aren't valid UTF-8 (e.g., `0xF1` for `ñ` from
  cp1252) won't store on UTF-8-strict shared volumes (Pure, some NFS
  appliances). Native ext4 / xfs is fine. Fix is `p4 move` to a clean name —
  see "Discovery" below.
- p4 binaries on disk follow `p4_<rel>.<bld>` symlinked to `p4_<inst>` —
  version upgrades swap the symlink, not the binary.

## Discovery: find paths with non-UTF-8 bytes

```bash
sudo -u perforce p4 verify -m1 //... 2>&1 \
  | grep -P '[\x80-\xff]' \
  | tee /tmp/non-utf8-paths.txt

# OR, walk the depot tree on disk
sudo find /p4/1/depots -name $'*\xf1*' 2>/dev/null
```

Once the list is in hand, a `p4 -c <client> move` per file (or batched in a
single submit) renames them to UTF-8-clean names. Coordinate with the depot's
consumers — Maya / Yeti / etc. scenes referencing the old literal paths will
break.

## Quick refs (open these first when paged)

- `sdp/doc/SDP_Guide.Unix.html` — full SDP guide
- `sdp/doc/DR-Failover-steps-Unix-standby.md` — failover procedure
- `/p4/common/bin/` — every script you might need
- `p4 help <command>` — beats Googling
- `p4 servers -J` — instant view of replica health across the estate
# Change User Description Committed
#1 32642 Russell C. Jackson (Rusty) SDP Cheat Sheet for quick reference.