I think that it might help to distinguish between a "release" and a "release candidate". If you really have shipped a version of software to other people and it is 'totally broken' then something went really very badly wrong. To avoid this opensource projects have milestone release and snapshot release (aka "nighly releases" or "freshly releases"). These try to flush out critical failures through pre-release public testing. Once the risk of shipping something totally broken has passed then the software is tagged as the final release. After that, if there are bugs, and there always are bugs, then it is a matter of issuing advisories and warning folks about bad old versions within release notes.
For example, spring.io releases are versioned something like "5.2.5.RELEASE". We might expect that they have a "5.2" branch and that they had many release candidate builds on that branch. In fact they have actually have two special repos for milestone releases and snapshot releases as described here. These approximate to beta releases and alpha releases.
If you are not releasing software to other people to run, but are running the software as a service yourself, then your option 3 may work well:
(3) Do no save information about release problems: just deploy a new stable, patched version to production and never look back.
This approach can work well if you are a building a web-app or mobile backend based product. The internal software at large firms like global banks will typically use this approach. In fact, I have worked on many systems at both banks and startups over two decades and we only ever used this approach in practice.
I should mention that your Git server might have a "latest release feature". Both GitHub and GitHub Enterprise have this. Even if you release via a build pipeline to some artefact repository it can still be helpful to make a "release" within the Git server so that an API call to something like GET /repos/:owner/:repo/releases/latest API will return details of the latest version including the git tag that should match the release version. Your deployment piplien can then pull the corresponding prebuilt code from the artefact server to deploy.