Skip to content

Hard-committed transaction causes false "update conflicts" on SuperClassic (5.0.3 and 5.0.4) #9017

Description

@Peter-1-1

Overview

A transaction that has been fully committed via COMMIT_TRANSACTION (hard commit) continues to be seen as active/concurrent by new attachments for up to 10+ minutes after the commit. This causes false deadlock / update conflicts with concurrent update errors referencing the already-committed transaction number.

The bug is confirmed on Firebird 5.0.3 (build 1683) and Firebird 5.0.4 (build 1812) under SuperClassic architecture.

This appears related to #8541 (fix-version 5.0.4), but the fix did not resolve this scenario.

Affected Versions

  • affect-version: 5.0.3, 5.0.4
  • Architecture: SuperClassic
  • OS: Ubuntu Linux x64
  • Hardware: 124GB RAM, 32-core AMD EPYC, NVMe RAID10 (dedicated DB server)

Steps to Reproduce

The issue occurs under concurrent load with multiple attachments from different source IPs modifying the same table. It has been observed with two different tables (T_URGENT_OPERS and REPL$LOG) and three different client applications (php-fpm7.2, php8.3, IBReplicator), confirming it is not application-specific.

Evidence: Firebird 5.0.4 (2026-05-01)

Transaction TRA_327149913 — committed successfully

2026-05-01T05:59:07.3460 START_TRANSACTION
    /data/INOUT-FB.FDB (ATT_190168728, REPL_R4:NONE, NONE, TCPv4:77.78.30.33/44328)
    /opt/IBReplicator/replserver:1575986
        (TRA_327149913, CONCURRENCY | WAIT | READ_WRITE)

[... executes SELECTs and DELETE FROM REPL$LOG WHERE SEQNO<=1011222617 ...]

2026-05-01T05:59:08.5220 COMMIT_TRANSACTION
    /data/INOUT-FB.FDB (ATT_190168728, REPL_R4:NONE, NONE, TCPv4:77.78.30.33/44328)
    /opt/IBReplicator/replserver:1575986
        (TRA_327149913, CONCURRENCY | WAIT | READ_WRITE)
      0 ms, 1 read(s), 16 write(s), 1 fetch(es), 1 mark(s)

Hard commit at 05:59:08.522, no errors.

False deadlock errors referencing TRA_327149913 AFTER commit

New IBReplicator attachments attempt DELETE FROM REPL$LOG WHERE SEQNO<=1011222525 (a subset of already-deleted-and-committed rows):

2026-05-01T06:07:36.7340 ERROR AT JStatement::execute
    /data/INOUT-FB.FDB (ATT_190196062, REPL_R4:NONE, NONE, TCPv4:77.78.30.33/54960)
335544336 : deadlock
335544451 : update conflicts with concurrent update
335544878 : concurrent transaction number is 327149913

2026-05-01T06:08:39.1270 ERROR AT JStatement::execute
    /data/INOUT-FB.FDB (ATT_190198069, REPL_R4:NONE, NONE, TCPv4:77.78.30.33/53506)
335544336 : deadlock
335544451 : update conflicts with concurrent update
335544878 : concurrent transaction number is 327149913

2026-05-01T06:09:45.1120 ERROR AT JStatement::execute
    /data/INOUT-FB.FDB (ATT_190201072, REPL_R4:NONE, NONE, TCPv4:77.78.30.33/58926)
335544336 : deadlock
335544451 : update conflicts with concurrent update
335544878 : concurrent transaction number is 327149913
  • Error 1: 8 minutes 28 seconds after commit
  • Error 2: 9 minutes 31 seconds after commit
  • Error 3: 10 minutes 37 seconds after commit

All three are from different attachments (ATT_190196062, ATT_190198069, ATT_190201072) — these are new connections, not long-lived ones with stale snapshots.

Evidence: Firebird 5.0.3 (2026-03-20) — same bug, different table

Transaction TRA_5791473 — committed successfully

2026-03-20T11:57:37.1090 START_TRANSACTION
    /data/TIP-TOP.FDB (ATT_4424969, SYSDBA:NONE, UTF8, TCPv4:172.16.3.85/49054)
    /usr/sbin/php-fpm7.2:3112708
        (TRA_5791473, CONCURRENCY | NOWAIT | READ_WRITE)

[... UPDATE T_URGENT_OPERS, INSERT T_WAYBILL_STATUSES_HISTORY ...]

2026-03-20T11:57:37.1230 COMMIT_TRANSACTION
    /data/TIP-TOP.FDB (ATT_4424969, SYSDBA:NONE, UTF8, TCPv4:172.16.3.85/49054)
        (TRA_5791473, CONCURRENCY | NOWAIT | READ_WRITE)
      0 ms, 1 read(s), 18 write(s), 1 fetch(es), 1 mark(s)

False deadlock errors referencing TRA_5791473 AFTER commit

2026-03-20T11:58:01.9540 ERROR (ATT_4425687, TCPv4:172.16.3.90)
    concurrent transaction number is 5791473
    At procedure 'P_SET_AWB_STATUS' line: 10
    At procedure 'P_SET_WH_SOFIA_STATUS' line: 22

2026-03-20T11:59:02.2300 ERROR (ATT_4427481, TCPv4:172.16.3.90)
    concurrent transaction number is 5791473

2026-03-20T12:00:01.5340 ERROR (ATT_4429365, TCPv4:172.16.3.90)
    concurrent transaction number is 5791473
  • Error 1: 24 seconds after commit
  • Error 2: 85 seconds after commit
  • Error 3: 144 seconds after commit

Different attachments, different source IP (172.16.3.90 vs 172.16.3.85), different application (php8.3 vs php-fpm7.2).

Impact

  1. False update conflicts: Transactions that should succeed are rejected.
  2. Stale reads (silent data inconsistency): If an attachment sees a committed transaction as active, it reads the OLD record version instead of the new one. Unlike update conflicts, stale reads produce NO error — the application silently works with outdated data.
  3. ACID violation: The Isolation guarantee of MVCC is broken — two concurrent connections can read different versions of the same committed data.

Analysis

The common factor across both cases:

  • SuperClassic architecture: each attachment has its own page cache
  • Hard COMMIT_TRANSACTION: not COMMIT_RETAINING
  • New attachments: the failing connections are brand-new (different ATT numbers, different source ports), not long-lived connections with old snapshots
  • TIP page propagation: after commit, the TIP (Transaction Inventory Page) is updated on disk, but other attachments' cached TIP copies are not invalidated/refreshed, so they continue to see the transaction as active

This is NOT #8541 (which was fixed in 5.0.4 for a replica journal scenario). The pattern here occurs on a primary (non-replica) server with regular application workload.

Relationship to Other Issues

Configuration

ServerMode = SuperClassic
DefaultDbCachePages = 8192
TempCacheLimit = 536870912          # 512MB
ReadConsistency = 1
GCPolicy = cooperative
ConnectionIdleTimeout = 60
MaxStatementCacheSize = 0           # disabled
MaxParallelWorkers = 32
ParallelWorkers = 20
DataTypeCompatibility = 2.5
AuthServer = Legacy_Auth, Srp, WinSspi
WireCrypt = Disabled
UserManager = Legacy_UserManager

Note: ReadConsistency = 1 is enabled — this uses the ReadConsistency snapshot isolation mode introduced in Firebird 4. This may be relevant as it changes how transaction snapshots and record version visibility are managed internally.

Server: 124GB RAM, 32-core AMD EPYC 4585PX, NVMe RAID10 (dedicated database server, no other services).
Concurrent sources: php-fpm7.2 (172.16.3.85, 172.16.3.87), php8.3 (172.16.3.90), IBReplicator (77.78.30.33). Approximately 100-200 concurrent connections during the observed incidents.

Trace Logs

Full fbtracemgr trace logs for both incidents are available upon request.

fb_debug_log.txt

Activity

  1. hvlad commented on May 1, 2026

    @hvlad
    Member

    Full fbtracemgr trace logs for both incidents are available upon request.

    Please, provide

  2. Peter-1-1 commented on May 1, 2026

    @Peter-1-1
    Author

    This is a full log for the time period. Short extract only for transaction 327149913 is in fb_debug_log.txt

  3. hvlad commented on May 1, 2026

    @hvlad
    Member

    Thanks.

    I can make a patch with enhanced tracing to gather more information about the issue.
    Is it OK for you to try such a build ?

  4. Peter-1-1 commented on May 2, 2026

    @Peter-1-1
    Author

    Yes I'm ok with the trace build

  5. BFuerchau commented on May 3, 2026

    @BFuerchau

    The main problem here is often the wrong handling of open ressources.
    I could see, that in MON$STATEMENTS often are statements visible, which are minutes old before they disappear.
    In the .Net-Client each object like Connection/Command/Reader has an Dispose() function to remove handles and clear internal ressources. I allways don't use the connection pool so the connection close really and no ressource is still available.
    So if you issue a commit you schould be shure, that you don't have any ressource open except the connection, you can than dispose and close.
    To prevent datatabse cache unload i have still an unsed connection open, that do every 30 seconds a single request to rdb$database within 1 transaction.

    No software is errorfree, so statements, transactions and connection are leave active if an application crashes, exception are thrown without dispose of resources or something else.
    So every database action should be within try/finally-Block to clear ressources.
    Sometimes it needs days, i don't know why, that holds transactions open and the database growths on high transaction load.
    Often only save/restore activities solve than the problem, which we do most 1 times á week.
    This i do since firebird 1.5;-).

  6. aafemt commented on May 3, 2026

    @aafemt
    Contributor

    The main problem here is often the wrong handling of open ressources.

    Attached trace clearly show that this is not the case.

    JFYI: Prepared statements are bound to attachment so it is normal if they live longer than transaction.

  7. BFuerchau commented on May 3, 2026

    @BFuerchau

    In MON$STATEMENTS i have often statements with state 0 (no more active, the process doesn't exists) but have also attached transaction, so the oldest interested transaction never increase and garbage not happens.
    With many transction ETL in the same table, the queries runs slower and slower because old data must be ignored.
    So we have attached a watcher process which try to delete these statements, older than 60 minutes, so transaction and connection can be closed from fbserver. But sometimes, these statements can not be deleted and the save/restore is needed.

  8. hvlad commented on May 3, 2026

    @hvlad
    Member

    Yes I'm ok with the trace build

    Please, use the appropriate build artifacts from this link
    Test in lab first!

  9. Peter-1-1 commented on May 4, 2026

    @Peter-1-1
    Author

    Hi Vlad,

    Thank you for the build!

    As a temporary workaround we switched to SuperServer — the issue has
    not appeared there so far.

    We plan to deploy the instrumented build this weekend (May 9-10),
    switch back to Classic to reproduce the bug, and report back with
    the trace logs.

    Best
    Peter

  10. Peter-1-1 commented on May 11, 2026

    @Peter-1-1
    Author

    Hi Vlad,
    I've sent you the full trace log to your email.
    Best
    Peter

  11. hvlad commented on May 11, 2026

    @hvlad
    Member

    Thanks, looking into it

  12. hvlad commented on May 13, 2026

    @hvlad
    Member

    Would you like to test new build ?

  13. Peter-1-1 commented on May 13, 2026

    @Peter-1-1
    Author

    Yes, is the build a fix or does it add additional debug data?

  14. hvlad commented on May 13, 2026

    @hvlad
    Member

    Additional debug\tracing.
    BTW, any interesting messages in firebird.log ?
    Also, what settings is changed in firebird.conf ?

  15. Peter-1-1 commented on May 13, 2026

    @Peter-1-1
    Author

    firebird.conf:
    DataTypeCompatibility = 2.5
    MaxParallelWorkers = 32
    ParallelWorkers = 20
    ServerMode = SuperClassic -- tested and with Classic - bug exist
    AuthServer = Legacy_Auth, Srp, WinSspi
    AuthClient = Legacy_Auth, Srp, WinSspi
    WireCrypt = Disabled
    UserManager = Legacy_UserManager
    ReadConsistency = 1 -- tested and with ReadConsistency = 0 - bug exist
    ConnectionIdleTimeout = 60
    MaxStatementCacheSize = 0
    DefaultDbCachePages = 8192
    TempCacheLimit = 536870912
    GCPolicy = cooperative

    There is no errors in firebird.log

    The first errors appear after 12 to 48 hours of operation - then they become more frequent

  16. 19 remaining items

  17. hvlad commented on Jul 31, 2026

    @hvlad
    Member
  18. hvlad commented on Aug 14, 2026

    @hvlad
    Member

    Peter, are you plan to test the new build?
    Or should I close the issue and be satisfied with the current patch?
    Just let me know, please.

  19. Peter-1-1 commented on Aug 14, 2026

    @Peter-1-1
    Author

    Hi,

    Due to the holiday period, I would be able to test the new build on September 4 at the earliest.

    So, if possible, please keep the issue open until then, and I’ll test the new build and provide feedback.

    Thanks for your patience.

    Best regards,
    Peter

  20. hvlad commented on Aug 14, 2026

    @hvlad
    Member

    Sure, thanks

  21. hvlad commented on Oct 21, 2026

    @hvlad
    Member

    Reminder...

  22. pcisar commented on Oct 22, 2026

    @pcisar
    Contributor

    I suppose the fix was tested internally? The severity calls for a permanent test scenario in Firebird QA suite. As embedded is always SuperClassic, the blast radius is not small. I really hope for fix in 5.0.5, otherwise we'll have to live with it for another year.

  23. Peter-1-1 commented on Oct 22, 2026

    @Peter-1-1
    Author

    Sorry, there are too many issues at the moment. I'll run the test again this Friday and provide a final answer on Monday.
    Best
    Peter Minev

  24. Peter-1-1 commented on Oct 26, 2026

    @Peter-1-1
    Author

    Hi Vlad,

    Quick status update: we are testing your latest commit (a108a04) on our production server in Classic mode since October 24, with transaction/error tracing enabled.

    After 48 hours there has been no reproduction of the bug:

    • no "TPC:" messages in firebird.log
    • no update conflicts where the concurrent transaction was committed before the victim's snapshot

    The plan is to keep the test running for one week. I'll report back with the final result.

    Best regards,
    Peter

  25. hvlad commented on Oct 26, 2026

    @hvlad
    Member

    Thanks!

  26. Peter-1-1 commented on Nov 2, 2026

    @Peter-1-1
    Author

    Hi Vlad,

    Final report on testing a108a04.

    Result: the bug did not reproduce.

    • No "TPC:" messages in firebird.log, and no crashes or restarts of the custom build during the whole week.

    • No false update conflicts: we checked every update conflict in the trace against the blocker's Commit number. All were legitimate (blocker committed after the victim's snapshot, or still active at the time of the error); the concurrent CN in the error always matched the Commit number in the trace.

    • TPC shared memory was fully re-created 6 times during the test (mostly at ~04:30, when all attachments were gone), with no issues after any of them.

    Thanks for the fix.
    Best regards,
    Peter

  27. hvlad commented on Nov 2, 2026

    @hvlad
    Member

    Thanks!

  28. added theissue type on Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions