SAP Buffers and Buffer Synchronization

In a distributed architecture, the database and instances can be on separate servers. Therefore the access to database from the application instances would have to resort to inter server communication over the network. If the data is not changed very frequently and not too big, caching it at the application’s memory can improve the access speed. Apart from improving the access speed, caching will prevent the load on the database. By reducing the database load, the need to add more CPU (and memory) can be avoided, which in turn reduces the licensing cost. SAP buffers are a part of the application memory that conceive this concept.

Buffer Synchronization

SAP buffers are local to each instance. When a change is made, the application instance where the transaction ran can be made aware of the change easily. However, it is very important to ensure that the changes are communicated to other application instances to ensure validity of the buffered information. This is realized by using the table DDLOG to centrally log and read the changes. The inevitable need to synchronize data across the application instances is the biggest challenge and a limitation to the type of data that is synchronized.

A change operation is first executed at the database level (but not committed yet), and if it is successful, the change is applied to the buffer. All the changes made to buffered objects are registered by the database interface of the work process in a main memory structure known as a “notebook”. At the end of the transaction, these registered synchronization requests are inserted to the NOTEBOOK field of DDLOG table. When the insert operation on DDLOG table completes, the database transaction is committed. The changes may not always be triggered by a transaction; a change could also be triggered by transports (tp and R3trans), but the technical realization of logging changes to DDLOG table remains the same. The newly created DDLOG data record is identified by a sequence number (SEQNUMBER field) that is automatically assigned in an ascending order by the database. In case of Oracle database, DDLOG_SEQ sequence takes care of sequencing.

The other application servers note the change as follows:
The dispatcher of the instance triggers buffer synchronization, which reads the new synchronization requests (since the last synchronization) from the table DDLOG. Only those sequence numbers that are higher than the previous sequence number are read to fetch the new entries from DDLOG. The new synchronization requests are applied to the buffers. The delay between two buffer synchronizations is determined by the parameter rdisp/bufreftime. This parameter (defaults 120 sec) should not be changed. If synchronization is required at a more frequent interval, then the buffering on the specific objects should be disabled or special access commands should be used to bypass the buffer.

Due to the delay in buffer synchronization (and performance reasons) transactional data should never be buffered.

The chief parameters to control buffer synchronization are:
rdisp/bufrefmode: Controls read and write on DDLOG table
rdisp/bufreftime (already discussed above): Controls the frequency of buffer synchronization

rdisp/bufrefmode defines (a) if synchronization records are written to the table DDLOG (possible values “sendon” or “sendoff”) and (b) if the periodic buffer invalidation occurs by reading synchronization records from the table DDLOG (possible values “exeauto” or “exeoff”). The parameter should be set to sendoff,exeauto if only one instance (the central instance) is configured. If there are more than one instances (i.e at least one dialog instance is installed in addition to the central instance), this parameter should be set to sendon,exeauto.

You may have noticed that the writing to DDLOG can be switched based on the number of instances, but reading is always turned on. The reason being that changes can also be made using R3trans or tp; such changes are always written to DDLOG and should always be read from DDLOG. exeoff can only be used for testing. If you set the parameter to exeoff, changes to repository objects in the database are not detected by the repository buffers.

The newer kernels or kernel patches automatically correct sendon/sendoff as change to rdisp/bufrefmode is usually forgotten when dialog instance is added to the central instance.

Error Situations in Buffer Synchronization

Let’s look at a few error situations that may affect buffer synchronizations

1. rdisp/bufrefmode set incorrectly
This is no longer a threat with the newer kernel releases and patches. If you are using older kernels and multiple instances, rdisp/bufrefmode should be set to “sendon,exeauto” on all the application instances, including the central instance.

2. DDLOG was not reset after a system copy
If you perform system refresh using database tools and methods instead of using SAP tools, DDLOG should be checked to ensure that it is empty. In such cases, you have to shut down all SAP instances and empty the records in DDLOG table.

3. Issues with DDLOG_SEQ on Oracle database
The SEQNUMBER field for each buffer synchronization record in DDLOG table is updated in ascending order by DDLOG_SEQ sequence.
a. If this sequence is missing, insert operations on DDLOG table will error out with return code ORA-02289 (LOG BY00>ORA-02289: sequence does not exist). In such cases, stop all the applications; truncate DDLOG table; create the missing seqnence using the following command and start the application:
create sequence ddlog_seq minvalue -2147483640 maxvalue 2147483640 increment by 1 cache 50 order nocycle;
b. If the maximum value of SEQNUMBER field is reached, insert operations on DDLOG table will error with a return code ORA-0800 (sequence DDLOG_SEQ.NEXTVAL exceeds MAXVALUE and cannot be instantiated).
To fix this error, stop the application instances; truncate DDLOG table; drop sequence ddlog_seq; recreate ddlog_seq sequence and start the application.
c. DDLOG_SEQ not updating the SEQNUMBER field on Oracle RAC
The creation of sequence in most SAP releases does not using “order” keyword explicitly. Since the default is noorder, the sequence is created using N flag for ORDER_FLAG column. This is usually not a problem if the Oracle database runs with a single instance. In case of Oracle RAC, the noorder can result in sequence numbers not being assigned in the time sequence. Buffer synchronization logic requires that the sequence numbers relate to time line in which they were created.
You can confirm the flag being used using the following SQL command:
select * from user_sequences where sequence_name = ‘DDLOG_SEQ’;
The fix to this problem is same as the previous fix (3b).

4. Dispatcher or work process problems
The buffer synchronization is triggered by the dispatcher and executed using dialog work process. If the dispatcher does not get enough CPU time or there are not enough dialog work processes, buffer synchronization does not happen. In such cases, you have to increase the trace level, reproduce the problem and engage SAP.

To increase the trace level:
Add the following parameters using RZ11
rdisp/TRACE_LOGGING = on, 150 m
Go to SM50 on each server, and increse the trace level from menu Process–> Trace –> Dispatcher –> Increase level