While testing EVENTACTIONS (SUSPEND) on an extract, I noticed that nothing in INFO tells you the process is suspended. The extract shows as RUNNING, the lag might look fine for a while, and yet it has stopped capturing. You may use SUSPEND on purpose (to pause an extract when a specific DDL goes by, for instance). Or someone else put it in a parameter file and you have to monitor the result. Either way, you need another way to know.
In the end, SEND EXTRACT ... STATUS is the only command that reports the suspended state, and it works the same way through the REST API, where the text is already parsed for you. A simpler check exists in the report file, generating an OGG-01281, but it has a limit I will show at the end.
In this blog, I will run an EXT1 extract capturing from PDB1. It has a DDL EVENTACTIONS trigger on a CREATE USER statement run in PDB1. The trigger suspends the extract whenever a user is created:
EXTRACT EXT1
USERIDALIAS pdb1 DOMAIN OracleGoldenGate
EXTTRAIL pdb1/e1
DDL INCLUDE ALL OBJTYPE 'USER' OPTYPE CREATE EVENTACTIONS (SUSPEND)
DDLOPTIONS REPORT
TABLE APP_PDB1.*;
Extract status before SUSPEND
Once started, the extract shows as RUNNING in INFO ALL:
OGG (http://vmogg:7810 ogg_test_01) 2> INFO ALL
Program Status Group Type Lag at Chkpt Time Since Chkpt
EXTRACT RUNNING EXT1 INTEGRATED 00:00:00 00:00:06
SEND EXTRACT EXT1 STATUS reports where the extract is in its life cycle. Here, the extract has nothing to capture, so the status is At EOF:
OGG (http://vmogg:7810 ogg_test_01) 2> SEND EXTRACT EXT1 STATUS
Sending STATUS request to Extract group EXT1 ...
EXTRACT EXT1 (PID 21617)
Current status: Recovery complete: At EOF
Current read position:
Redo thread #: 0
Sequence #: 0
RBA: 0
Timestamp: 2026-09-26 06:26:24.000000
SCN: 0.115334476 (115334476)
Current write position:
Sequence #: 11
RBA: 6942
Timestamp: 2026-09-26 06:26:20.463368
Extract Trail: pdb1/e1
Suspending the extract
Let’s create a user in PDB1, which matches the DDL rule:
SQL> CREATE USER SUSPTEST IDENTIFIED BY "Suspend_Test_1";
User created.
Half a minute later, INFO EXT1 still says RUNNING with a lag of 0 seconds, but the checkpoint was last updated 30 seconds ago:
OGG (http://vmogg:7810 ogg_test_01) 2> INFO EXT1
Extract EXT1 Last Started 2026-09-26 06:26 Status RUNNING
Checkpoint Lag 00:00:00 (updated 00:00:30 ago)
Process ID 21617
Log Read Checkpoint Oracle Integrated Redo Logs, per-PDB
2026-09-26 06:26:18
SCN 0.115334462 (115334462)
Encryption Profile LocalWallet
No Replicat groups found, but some coordinated threads may have been excluded.
Two minutes after the CREATE USER, the same command gives:
OGG (http://vmogg:7810 ogg_test_01) 2> INFO EXT1
Extract EXT1 Last Started 2026-09-26 06:26 Status RUNNING
Checkpoint Lag 00:00:00 (updated 00:02:00 ago)
Process ID 21617
Log Read Checkpoint Oracle Integrated Redo Logs, per-PDB
2026-09-26 06:26:18
SCN 0.115334462 (115334462)
Encryption Profile LocalWallet
No Replicat groups found, but some coordinated threads may have been excluded.
The status is still RUNNING, and the lag value does not grow: Checkpoint Lag stays at 00:00:00. What grows is the time since the checkpoint was updated (updated 00:00:30 ago, then updated 00:02:00 ago), and the checkpoint position (SCN 0.115334462) never moves. That is a hint that something is wrong (or right), but nothing in this output says it is a suspend.
SEND EXTRACT STATUS shows the suspended state
Now the same SEND EXTRACT EXT1 STATUS as before:
OGG (http://vmogg:7810 ogg_test_01) 2> SEND EXTRACT EXT1 STATUS
Sending STATUS request to Extract group EXT1 ...
EXTRACT EXT1 (PID 21617)
Current status: Recovery complete: Suspended, waiting to be resumed
Current read position:
Redo thread #: 1
Sequence #: 3045
RBA: 58777616
Timestamp: 2026-09-26 06:26:27.000000
SCN: 0.115334507 (115334507)
Current write position:
Sequence #: 11
RBA: 6942
Timestamp: 2026-09-26 06:26:20.463368
Extract Trail: pdb1/e1
Comparing the two outputs, the only line that tells you the extract is suspended is Current status:
- Before:
Current status: Recovery complete: At EOF. It could have been some other message if it was still extracting. - After:
Current status: Recovery complete: Suspended, waiting to be resumed
Everything else in INFO is compatible with a healthy extract. To resume it, run SEND EXTRACT EXT1 RESUME.
Which command shows the suspend?
STATUS EXTRACT looks like the natural command, but it is not the same as SEND EXTRACT ... STATUS. On the suspended extract, STATUS EXTRACT gives:
OGG (http://vmogg:7810 ogg_test_01) 4> STATUS EXTRACT EXT1
EXTRACT EXT1: RUNNING
INFO EXT1 DETAIL adds the trail, the outbound server SCNs and the file locations, but its header is the same as INFO EXT1:
OGG (http://vmogg:7810 ogg_test_01) 5> INFO EXT1 DETAIL
Extract EXT1 Last Started 2026-09-26 06:26 Status RUNNING
Checkpoint Lag 00:00:00 (updated 00:02:00 ago)
Process ID 21617
Log Read Checkpoint Oracle Integrated Redo Logs, per-PDB
2026-09-26 06:26:18
SCN 0.115334462 (115334462)
Encryption Profile LocalWallet
Target Extract Trails:
Trail Name Seqno RBA Max MB Trail Type
pdb1/e1 11 6942 2000 EXTTRAIL
Integrated Extract outbound server first scn: 0.115313606 (115313606)
Integrated Extract outbound server filtering start scn: 0.115313606 (115313606)
| Command | Before the suspend | After the suspend |
|---|---|---|
INFO ALL | RUNNING | RUNNING |
INFO EXT1 | RUNNING | RUNNING |
INFO EXT1 DETAIL | RUNNING | RUNNING |
STATUS EXTRACT EXT1 | RUNNING | RUNNING |
SEND EXTRACT EXT1 STATUS | Recovery complete: At EOF | Recovery complete: Suspended, waiting to be resumed |
Only SEND EXTRACT ... STATUS shows the suspend. STATUS EXTRACT, like INFO, just reports the state of the process.
Getting the status with the REST API
The SEND commands are available through the /services/{version}/extracts/{extract}/command endpoint, and the response already contains the parsed status.
With the oggrestapi Python client
With the GoldenGate Python client, execute_command_extract sends the request. First, initialize the client:
>>> from oggrestapi import OGGRestAPI
>>> ogg_client = OGGRestAPI(
url='http://vmogg:7810',
username='ogg',
password='ogg'
)
Connected to OGG REST API at http://vmogg:7810
Here is the raw output given by the execute_command_extract method:
>>> resp = ogg_client.execute_command_extract('EXT1', data={'command': 'STATUS'})
>>> resp
{'$schema': 'er:commandResult', 'reply': 'OKNODOT\tEXTRACT EXT1 (PID 41522)\n Current status: Recovery complete: Suspended, waiting to be resumed\n\n Current read position:\n Redo thread #: 1\n Sequence #: 3047\n RBA: 92686352\n Timestamp: 2026-09-26 08:48:41.000000\n SCN: 0.115434621 (115434621)\n Current write position:\n Sequence #: 1\n RBA: 5679\n Timestamp: 2026-09-26 08:48:37.669072\n Extract Trail: pdb1/r1\n\n', 'replyData': {'$schema': 'er:statusResult', 'status': {'groupName': 'EXT1', 'processId': '41522', 'processType': 'extract', 'status': 'Recovery complete: Suspended, waiting to be resumed', 'extractReadingPosition': [{'$schema': 'dbms:positionInfo', 'position': {'redoThread': 1, 'csn': 115434621, 'seqno': 3047, 'rba': 92686352, 'timestamp': '2026-09-26T08:48:41.000Z'}}], 'extractWritingPosition': [{'$schema': 'ogg:trailPosition', 'sequence': 1, 'offset': 5679, 'name': 'r1', 'path': 'pdb1/'}]}}}
In GoldenGate REST API, the status is available in replyData.status.status:
>>> resp['replyData']['status']['status']
'Recovery complete: Suspended, waiting to be resumed'
To avoid repeating the replyData navigation everywhere, custom methods are available in oggrestapi:
def get_extract_status_detail(self, extract):
result = self.execute_command_extract(extract, data={'command': 'STATUS'})
return str(result.get('replyData', {}).get('status', {}).get('status', ''))
def is_extract_suspended(self, extract):
return 'suspended' in self.get_extract_status_detail(extract).lower()
>>> ogg_client.get_extract_status_detail('EXT1')
'Recovery complete: Suspended, waiting to be resumed'
>>> ogg_client.is_extract_suspended('EXT1')
True
With the requests module
Without the client, send STATUS as the command with the requests library:
import requests
url = 'http://vmogg:7810/services/v2/extracts/EXT1'
auth = ('ogg', 'ogg')
response = requests.post(f'{url}/command', auth=auth, json={'command': 'STATUS'}).json()['response']
The response contains the same replyData field, with the status already extracted:
>>> response['replyData']['status']['status']
'Recovery complete: Suspended, waiting to be resumed'
Note that this is not the same as the info/status endpoint, which returns the process state as INFO does. It says running for a suspended extract, but it holds the two values behind the lag line of INFO:
>>> requests.get(f'{url}/info/status', auth=auth).json()['response']
{'$schema': 'ogg:extractStatus', 'status': 'running', 'processId': 21617, 'lastStarted': '2026-09-26T06:26:09.798Z', 'lag': 0, 'sinceLagReported': 125, 'position': '0.115334462'}
lag is the checkpoint lag of INFO, and sinceLagReported is the updated ... ago value in seconds.
Adding a lag check
For a monitoring script, the status can be paired with a lag check. get_extract_status costs a single GET call, and a healthy extract keeps updating its checkpoint. A large sinceLagReported is a cheap first filter before sending the STATUS command:
>>> status = ogg_client.get_extract_status('EXT1')
>>> status['status'] == 'running' and status['sinceLagReported'] > 60 and ogg_client.is_extract_suspended('EXT1')
True
When this returns True, you have a running extract that has not moved for more than a minute and that reports itself as suspended. Whether you should then resume it depends on why the SUSPEND was there in the first place. An alert is usually the right answer. If you do want to resume it from the script, it is another execute_command_extract call:
>>> ogg_client.execute_command_extract('EXT1', data={'command': 'RESUME'})
A simpler check: OGG-01281 in the report
The suspend also leaves a trace in the extract report file, with the OGG-01281 message:
2026-09-26 06:26:29 INFO OGG-00487 DDL operation included [INCLUDE ALL OBJTYPE 'USER' OPTYPE CREATE EVENTACTIONS (SUSPEND)], optype [CREATE], objtype [USER], objowner "", objname "SUSPTEST".
2026-09-26 06:26:30 INFO OGG-01281 Processed SUSPEND event from DDL on object name SUSPTEST, DDL seqno 0, marker seqno 0.
Is this message specific to SUSPEND? To check it, I ran the same DDL rule with other EVENTACTIONS, recreating the user each time:
# DDL INCLUDE ALL OBJTYPE 'USER' OPTYPE CREATE EVENTACTIONS (ROLLOVER)
2026-09-26 06:29:32 INFO OGG-01285 Processed ROLLOVER event from DDL on object name SUSPTEST, DDL seqno 0, marker seqno 0.
# DDL INCLUDE ALL OBJTYPE 'USER' OPTYPE CREATE EVENTACTIONS (LOG INFO)
2026-09-26 06:30:37 INFO OGG-06117 Processed LOG event from DDL on object name SUSPTEST, DDL seqno 0, marker seqno 0.
# DDL INCLUDE ALL OBJTYPE 'USER' OPTYPE CREATE EVENTACTIONS (LOG WARNING)
2026-09-26 06:31:40 WARNING OGG-06118 Processed LOG event from DDL on object name SUSPTEST, DDL seqno 0, marker seqno 0.
ROLLOVER raises OGG-01285, and LOG raises OGG-06117 (or OGG-06118 with WARNING). IGNORE raises nothing at all beyond the OGG-00487 line. So OGG-01281 is only raised by SUSPEND.
The limit of this check is that the report is a history, not a state. When resuming the extract, the OGG-01281 line stays in the report, and a new message is written after it:
2026-09-26 06:26:30 INFO OGG-01281 Processed SUSPEND event from DDL on object name SUSPTEST, DDL seqno 0, marker seqno 0.
2026-09-26 06:28:29 INFO OGG-01824 Resume processing from SUSPEND state for process EXT1.
Finding OGG-01281 in the report does not mean the extract is suspended now. You have to check that no OGG-01824 comes after it. On top of that, the report is rolled over at each restart of the extract, so it only covers the current run. With the REST API, the report is available through get_extract_report, whose lines key contains the list of lines:
>>> report = ogg_client.get_extract_report('EXT1', 'EXT1.rpt')
>>> [line for line in report['lines'] if 'OGG-01281' in line or 'OGG-01824' in line]
['2026-09-26 06:26:30 INFO OGG-01281 Processed SUSPEND event from DDL on object name SUSPTEST, DDL seqno 0, marker seqno 0.']
This is useful to find out when and why the extract was suspended, since the message contains the object that triggered it. But to know whether it is suspended right now, STATUS is the reliable way.
The full check in one script
Here is a small script with everything seen in this blog. It runs the lag check, the suspend check, and the log analysis to find the culprit, then prints an info message.
from oggrestapi import OGGRestAPI
ogg_client = OGGRestAPI(url='http://vmogg:7810', username='ogg', password='ogg')
extract = 'EXT1'
status = ogg_client.get_extract_status(extract)
# Lag check: a running extract whose checkpoint has not moved for a minute
if status['status'] == 'running' and status['sinceLagReported'] > 60:
# Suspend check
if ogg_client.is_extract_suspended(extract):
# Log analysis: the last OGG-01281 or OGG-01824 tells who suspended it
report = ogg_client.get_extract_report(extract, f'{extract}.rpt')
events = [line for line in report['lines'] if 'OGG-01281' in line or 'OGG-01824' in line]
if events and 'OGG-01281' in events[-1]:
print(f'INFO: {extract} is suspended. Culprit: {events[-1]}')
else:
print(f'INFO: {extract} is suspended, but no OGG-01281 in the current report')
else:
print(f'INFO: {extract} is not suspended, but its checkpoint has not moved for {status["sinceLagReported"]} seconds')
else:
print(f'INFO: {extract} is not suspended')
INFO: EXT1 is suspended. Culprit: 2026-09-26 06:26:30 INFO OGG-01281 Processed SUSPEND event from DDL on object name SUSPTEST, DDL seqno 0, marker seqno 0.
What about replicats?
It works the same way for a replicat. I tested it with an integrated replicat applying the trail of EXT1, with DDL INCLUDE ALL OBJTYPE 'USER' OPTYPE CREATE EVENTACTIONS (SUSPEND) in its parameter file. INFO reports RUNNING, and SEND REPLICAT REP1 STATUS reports the suspended state. is_replicat_suspended returns True, and SEND REPLICAT REP1 RESUME resumes it with an OGG-01824.
The suspend is still logged with OGG-01281, but the culprit is not named. The replicat suspends before applying the DDL, so the report says object name N/A. The user name only appears in the OGG-00487 line after the resume operation:
2026-09-26 08:56:19 INFO OGG-01281 Processed SUSPEND event from DDL on object name N/A in file /u01/app/ogg/deployments/ogg_test_01/var/lib/data/pdb1/q1000000000, RBA 5284.
2026-09-26 08:58:02 INFO OGG-01824 Resume processing from SUSPEND state for process REP1.
2026-09-26 08:58:02 INFO OGG-00487 DDL operation included [INCLUDE ALL OBJTYPE 'USER' OPTYPE CREATE EVENTACTIONS (SUSPEND)], optype [CREATE], objtype [USER], objowner "", objname "SUSPTEST".
Summary
To know whether a GoldenGate extract is suspended by an EVENTACTIONS (SUSPEND) rule:
- Do not rely on
INFO ALL,INFO,INFO DETAILorSTATUS EXTRACT. They all reportRUNNING, and the checkpoint lag stays the same. Only theupdated ... agovalue grows. - Run
SEND EXTRACT EXT1 STATUSin theadminclient:Current status: Recovery complete: Suspended, waiting to be resumedappears when the extract is suspended. - In a script, use
is_extract_suspendedfrom the Python client, or send the sameSTATUScommand to/services/v2/extracts/EXT1/commandand readreplyData.status.status. - Filter with
sinceLagReportedfrominfo/status(for instance more than 60 seconds) before sending theSTATUScommand. - Use
OGG-01281in the report to find out when and why the extract was suspended, and check that noOGG-01824came after it. - Resume with
SEND EXTRACT EXT1 RESUME, or with theRESUMEcommand throughexecute_command_extract.