Sunday, 9 August 2026

Sometimes It Is Not One Big Problem. It Is Everything Running in the Background.


After more than 12 years of working with production databases, I have learned that performance problems do not always begin with one terrible query.

Sometimes it is several smaller things happening together. One session is using slightly more CPU, another is holding a lock, a background job is running longer than expected, and storage latency has quietly increased. None of them looks disastrous alone, but together they make the whole system struggle.

Stress can build in much the same way.

We usually search for one obvious reason when we feel exhausted: a difficult project, a production incident, financial pressure, or a problem at home.

But sometimes there is no single cause. It is the late-night message we answered, the lunch we skipped, the conversation we kept replaying, the water we forgot to drink, and the sleep we sacrificed because one task was still pending

Each one appears manageable. Together, they become a collection of background processes that nobody remembered to stop.


The Small Things That Keep Us Switched On


Lesson 1: Work Never Completely Ends

Anyone working in production support knows that some situations cannot wait. If a critical database is unavailable, “Let us check tomorrow morning” is unlikely to be accepted as a recovery plan.

But not every email is an incident. Not every Teams message is an escalation. And not every sentence beginning with “quick question” will actually be quick.

When work follows us into every evening, the laptop may be closed, but the mind remains connected. We continue thinking about tomorrow’s change, an unresolved ticket, or the possibility that another message might arrive.

Effectively, the brain remains on call—usually without claiming the allowance.

There needs to be a reasonable difference between being responsible and being permanently available.


Lesson 2: We Postpone the Basics First

During a busy day, lunch is often treated as an optional dependency.

We plan to eat after the next meeting. Then another call starts, a ticket is escalated, and lunch finally happens at 4:30 PM. That is not necessarily intermittent fasting. Sometimes it is simply poor calendar management.

Water, movement, and sleep are handled in much the same way. The body may tolerate this for a while, which can make us believe everything is fine. However, inadequate sleep can affect attention, mood, and emotional regulation, making ordinary problems feel harder the following day.

No productivity application can fully compensate for repeatedly ignoring the basics—not even the one with the attractive dashboard.


Lesson 3: Some Meetings Continue in Our Heads

We have all attended a meeting that officially ended at 3:00 PM but continued in our mind until bedtime.

Perhaps someone spoke unfairly. Maybe an important question remained unanswered. We replay the discussion and prepare several excellent responses—unfortunately, all of them arrive four hours too late.

It is unrealistic to expect every emotion to disappear when a meeting ends. A more practical approach is to write down what happened, decide whether an action is required, and set a time to deal with it.

Otherwise, a 30-minute conversation can occupy mental storage for the rest of the day.


Lesson 4: Notifications Create Invisible Work

One notification does not seem stressful. The problem is the repeated switching

You are reviewing a document when a Teams message appears. Then an email arrives, the phone vibrates, and somebody requests a “small update” in another channel. By evening, you have been active for nine hours but are not entirely sure what you completed.

Research suggests that notifications can interrupt attention even when we do not open them. Turning off unnecessary alerts does not mean becoming unreachable. It means deciding which applications genuinely deserve permission to interrupt you.

If five applications are all marked as urgent, perhaps none of them understands the meaning of urgent.


Lesson 5: Sitting All Day Does Not Help

DBAs can spend several hours in the same chair, particularly during an incident, production change, or troubleshooting call.

At some point, the chair knows more about the shift schedule than the family does.

Movement does not have to mean a full gym session. A short walk after lunch, standing during a call, or stepping away from the screen between meetings can break a long period of sitting.

A ten-minute walk will not resolve chronic stress or fix the execution plan. It can, however, give the mind a useful pause.


Lesson 6: Not Every Energy Dip Is a Blood-Sugar Problem

Tiredness, irritability, and poor concentration are frequently blamed on a “blood-sugar crash.” That explanation is often too simple.

The same symptoms may be related to poor sleep, dehydration, irregular meals, stress, medication, or an underlying health condition. An afternoon slump alone is not enough to conclude that someone has hypoglycaemia.

Regular, balanced meals are a sensible starting point. If fatigue, dizziness, or other unexplained symptoms continue, speak with a qualified medical professional. Google, a smartwatch, and one motivational video do not constitute a clinical team.


Lesson 7 Connection Matters More Than We Admit

When work becomes intense, personal time is often the first item removed from the calendar.

We postpone meeting friends, speak less with family, and remain half-connected to the phone even when we are with people; just in case the world ends while we are having dinner.

Supportive relationships cannot remove difficult circumstances, but they can make those circumstances easier to manage. Sometimes a relaxed conversation with someone we trust is more useful than another hour spent trying to optimise ourselves.


Recovery May Begin with Subtraction

When a database is overloaded, we do not always solve the problem by adding more resources. Sometimes we stop an unnecessary job, reduce repeated calls, correct an inefficient query, or remove work that should never have been running.

The same principle can apply to us.

Recovery may not begin with another tracking application, a complicated morning routine, or ten new habits that eventually become eleven new sources of guilt.

It may begin with something much simpler:

  • Turn off one unnecessary notification.
  • Decline one meeting that does not need to happen.
  • Eat lunch without looking at a screen.
  • Leave one genuinely non-urgent message until tomorrow.
  • Allow an empty space in the calendar to remain empty.

The objective is not to eliminate every source of stress. Some pressure is unavoidable, particularly in roles carrying operational responsibility. The problem begins when pressure becomes continuous and recovery is repeatedly postponed.

We spend a great deal of time monitoring the health of our systems. Occasionally, we should check what has been running in our own background for too long.

Not every alert requires a P1 response—but please understand the alert before muting it and going for coffee.

Stay healthy.



Oracle Redo Logs: Sizing Without Guesswork

Redo log problems rarely start with a clean error message. They usually show up as slow commits, archive destinations filling faster than expected, Data Guard apply lag, or batch jobs that suddenly take longer during month-end. By the time someone checks the alert log, the database may already be switching logs too frequently, checkpointing aggressively, or waiting for archiving to catch up.

A common reaction is to increase redo log size and move on. Sometimes that is required, but it is not always the real fix. Redo log sizing controls how frequently Oracle switches logs. It does not reduce the amount of redo generated by bad SQL, unnecessary indexes, row-by-row commits, or poorly designed batch jobs.

This post looks at Oracle redo log sizing from a production DBA angle. We will check log switch frequency, estimate redo generation rate, review MTTR guidance, discuss common failure scenarios, and compare the idea briefly with PostgreSQL WAL pressure.



Saturday, 8 August 2026

Oracle 26ai AWR Enhancements for DBAs

 AWR used to be simple when most databases were single-instance, single-tenant, and all important workload stayed on the primary database.

That world is mostly gone.

Today, one CDB may host multiple PDBs. Reporting may run on Active Data Guard. Read traffic may be pushed toward True Cache. Replication may be handled through GoldenGate or XStream. When performance breaks, the first question is no longer just “what was the top wait event on the database?”



Saturday, 25 July 2026

pg_switch_wal() in PostgreSQL: Small Command, Big Recovery Impact

A PostgreSQL database can look completely healthy until the day you try to restore it.


Backups are available. WAL archiving is enabled. The archive directory has files. Monitoring shows green. Then, during PITR, PostgreSQL throws something like:


could not locate required checkpoint record

or recovery stops before the target time because the WAL needed for that moment was never archived.

This is where many DBAs learn an uncomfortable lesson: the WAL segment that contains the changes you need may still be sitting inside pg_wal/ as the active segment. It has not filled up yet, so the archiver has not copied it.

On a busy system, WAL segments rotate quickly. On a quiet database, the same 16 MB segment may remain open for hours or even days.

pg_switch_wal() is the function that forces PostgreSQL to close the current WAL segment and move to the next one.
It sounds simple. In recovery work, backup validation, and archive troubleshooting, it is extremely useful.


What pg_switch_wal() Actually Does

PostgreSQL writes every change to the Write-Ahead Log before the actual data file change is considered safe. WAL is split into segment files, normally 16 MB each, stored under pg_wal/.

A typical WAL file looks like this:
000000010000000000000019

That filename contains: Timeline ID Log ID & Segment number
Normally, PostgreSQL closes a WAL segment only when it becomes full.

 When you execute:

SELECT pg_switch_wal();


PostgreSQL forces the active WAL segment to finish early and starts writing into a new segment.
Operationally, this means:
  • Current WAL segment is closed
  • Remaining space is padded
  • Next WAL segment becomes active
  • Closed segment becomes ready for archiving
  • Function returns the LSN where the switch happened

The return value may look like this: 0/2B7A9C0

That is the LSN where the WAL switch happened.

0 = upper 32 bits of the byte position
2B7A9C0 = lower 32 bits in hexadecimal

Converting: 0x2B7A9C0 = 45,590,976 bytes, approximately 43.5 MB into the WAL stream.

With a 16 MB WAL segment size, this position falls inside the second WAL segment of that timeline range. To identify the WAL file name:

SELECT pg_walfile_name('0/2B7A9C0');

That tells you which WAL segment contains that LSN.

Small detail, but useful during recovery: the returned LSN is the switch location. The file containing that LSN is the segment that was active at the time of the switch and should now become available for archiving.



Why DBAs Use It Before Recovery Testing

The most practical use of pg_switch_wal() is not academic. It is recovery safety.


Imagine this situation:
10:00 - Base backup completed
10:15 - Application made important changes
10:20 - You want PITR to 10:15

But the database is quiet. The WAL segment containing the 10:15 changes is still open. It has not reached 16 MB. Since it is not complete, the archiver has not copied it yet.

Now your archive location looks fine, but recovery does not have the WAL required to reach 10:15.

Before running PITR tests or relying on a precise recovery target, force a WAL switch:
SELECT pg_switch_wal();

Then check whether the segment arrived in the archive destination:

SELECT
    archived_count,
    last_archived_wal,
    last_archived_time,
    failed_count,
    last_failed_wal,
    last_failed_time
FROM pg_stat_archiver;
If last_archived_wal does not move, do not trust your recovery setup yet.


A lot of backup checks only validate that a base backup exists. That is not enough. PostgreSQL recovery needs both the base backup and the required WAL chain.


Missing one WAL file can make an otherwise good backup useless.


Using It to Validate Archive Command

pg_switch_wal() is also one of the fastest ways to test whether archiving is actually working.


First check archive settings:
    SHOW archive_mode;
    SHOW archive_command;

Then force a WAL switch:
    SELECT pg_switch_wal();

Now check archiver status:

SELECT
    archived_count,
    last_archived_wal,
    last_archived_time,
    failed_count,
    last_failed_wal,
    last_failed_time
FROM pg_stat_archiver;

On the OS side, check the archive destination:

ls -ltr /app/postgres/arch/

If the archive command is correct, a new WAL file should appear shortly.

If not, check PostgreSQL logs. Most archive failures are boring but painful:
  • Permission denied
  • Destination full
  • Wrong path
  • NFS stale mount
  • archive_command returns non-zero exit code
  • File already exists
A bad archive command can sit unnoticed for a long time if nobody monitors failed_count.


This is a common DBA blind spot. People monitor database availability, replication lag, and CPU. But archiver failures are often discovered only during restore.

That is too late.




The No-Op Behavior That Confuses People

There is one nuance DBAs should remember. pg_switch_wal() may do nothing if no WAL has been generated since the last switch.

So if you run this twice:
    SELECT pg_switch_wal();
    SELECT pg_switch_wal();

the second call may return the same or nearly same LSN. That does not mean PostgreSQL is broken. It means there was nothing new to switch. To force WAL activity, generate some WAL first.

For example:

CREATE TABLE wal_test_tmp(id int);
DROP TABLE wal_test_tmp;

SELECT pg_switch_wal();
Or, depending on the test:

CHECKPOINT; SELECT pg_switch_wal();

Be careful with unnecessary forced switches on busy systems. Every switch creates a new WAL segment for archiving. If someone puts this into a frequent cron job without thinking, archive volume can increase, storage can fill faster, and backup systems may process more WAL files than needed.

Useful command. Bad habit if abused.




Production Failure Scenarios

1. PITR Fails Even Though Backup Exists

Symptoms:

  • Recovery starts
  • WAL restore works for some files
  • Recovery stops before target time
  • Required checkpoint record not found

Typical cause: The WAL segment containing the target time was never archived.

Fix: SELECT pg_switch_wal();

Then verify:

SELECT last_archived_wal, last_archived_time
FROM pg_stat_archiver;
Operational lesson: never validate PostgreSQL recovery using only the presence of base backups.


2. Archive Destination Fills Up

Symptoms:

  • WAL files accumulating in pg_wal
  • archive_command failing
  • Database disk usage increasing

Check: SELECT failed_count, last_failed_wal, last_failed_time FROM pg_stat_archiver;

OS check: 

df -h

du -sh /home/postgres/arch/

If archiving is broken long enough, pg_wal can grow and eventually threaten database availability.



3. Standby or Backup Lag Caused by WAL Handling


In streaming replication or backup-heavy systems, WAL is the lifeline. If archiving is delayed, replicas or restore jobs may fall behind or fail to fetch required segments.

SELECT
    pg_current_wal_lsn(),
    pg_walfile_name(pg_current_wal_lsn());

For replication:

SELECT
    application_name,
    state,
    sent_lsn,
    write_lsn,
    flush_lsn,
    replay_lsn,
    sync_state
FROM pg_stat_replication;

pg_switch_wal() will not fix a bad replica by itself. But it helps validate whether WAL generation and archiving are behaving as expected.


DBA Insights

Do not treat pg_switch_wal() as a magic recovery command. It does one thing: it closes the current WAL segment and makes it eligible for archiving.

The real DBA work is around validation.

Check whether archiving is enabled:

SHOW archive_mode;

Check whether the command is sane:

SHOW archive_command;

Check whether archiving is progressing:

SELECT archived_count, last_archived_wal, last_archived_time FROM pg_stat_archiver;

Check whether failures are increasing:

SELECT failed_count, last_failed_wal, last_failed_time FROM pg_stat_archiver;

And always check from the OS side:

ls -ltr /home/postgres/arch/

df -h


Common mistakes I have seen:

Assuming base backup success means PITR is safe
Not monitoring pg_stat_archiver
Forgetting quiet databases may not archive WAL quickly
Running pg_switch_wal too frequently without storage planning
Not testing restore until an actual incident
Ignoring archive_command failures because the database is still online

The most dangerous backup system is the one that has never been restored.


FAQs

Does pg_switch_wal() force WAL archiving?

Not directly. It closes the current WAL segment. Once the segment is complete, the archiver can pick it up if archive_mode is enabled and archive_command is working.


Why did pg_switch_wal() return the same LSN twice?

Most likely no WAL was generated between the two calls. Generate a small change, then run it again.


Is it safe to run in production?

Yes, but do not abuse it. Occasional use for backup, PITR validation, or archive testing is normal. Frequent forced switches can increase archive file count and storage pressure.


How do I know the switched WAL was archived?

SELECT last_archived_wal, last_archived_time FROM pg_stat_archiver;
Then confirm at the archive destination: ls -ltr /home/postgres/arch/


Can this fix broken PITR?

It can help if the required WAL is still in the active segment and has not yet been archived. It will not help if the WAL was already lost, deleted, or never generated.


Conclusion

pg_switch_wal() is a small PostgreSQL function, but it sits right in the middle of backup confidence, WAL archiving, and PITR reliability.


It is useful before restore testing, after important changes, and while validating archive behavior. But the command itself is only part of the story. The real discipline is checking whether the WAL segment reached the archive location and whether recovery can actually consume it.


A good DBA does not stop at “backup completed.”
A good DBA asks:
  • Can I restore it?
  • Can I recover to the required time?
  • Do I have every WAL file needed?
  • Did I test this before the outage?
That mindset saves production systems.



Saturday, 18 July 2026

The Outage Usually Begins Before the Database Fails

A database incident rarely begins when the monitoring system raises an alert. It usually begins weeks earlier - with an unreviewed execution plan, an ignored capacity trend, an oversized privilege, or a recovery procedure that nobody has tested.

By the time the DBA receives the call, the database is often exposing an operational weakness that was already present. The immediate symptom may be exhausted storage, a failed deployment, excessive I/O, or a missing object, but the underlying cause is frequently a gap in engineering discipline.

I have seen expensive Oracle platforms fail because nobody noticed that the Fast Recovery Area was growing rapidly. I have also seen relatively modest PostgreSQL environments remain stable for years because the team consistently reviewed changes, monitored capacity, controlled access, and tested recovery.



Monday, 13 July 2026

RESETLOGS and Backups: Debunking a Common Oracle Myth

 If you have ever recovered an Oracle database and opened it with RESETLOGS, chances are someone whispered or shouted—the dreaded question: “Are all my old backups now useless?” Lets set the record straight: in modern Oracle releases, your old backups are still very much usable, and panicking is optional.

In this post, I wil walk you through why this myth exists, how Oracle’s handling of RESETLOGS has evolved over the years, and what you should do to ensure your recovery strategy remains solid. We will cover the mechanics of RESETLOGS, explain the differences between pre-10g version and modern behaviour, and share some practical tips I have learned from managing production environments with terabytes of data. By the end, you you will understand why you can sleep a little easier after recovery and make smarter backup decisions.



Saturday, 4 July 2026

DB Time vs CPU: The Metric Most DBAs Ignore

 If you have worked in production environments long enough, you have probably seen this situation before. An alert fires in the middle of your daily shift appears.. as "CPU is at 90%. The database must be overloaded." 

Infrastructure teams immediately start discussing scaling CPU, adding cores, or moving the database to a bigger server. But experienced DBAs know something important: High CPU utilization does not automatically mean the database is the bottleneck.