# Issue with Trigger Causing Update Errors in Busy Node on Galera Cluster

**URL:** <https://forums.percona.com/t/issue-with-trigger-causing-update-errors-in-busy-node-on-galera-cluster/40337>\
**Category:** Percona XtraDB Cluster 8.x\
**Tags:** mysql, percona\
**Created:** [March 5, 2026, 5:49pm UTC](https://forums.percona.com/t/issue-with-trigger-causing-update-errors-in-busy-node-on-galera-cluster/40337 "2026-03-05T17:49:33Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nazmul](https://avatars.discourse-cdn.com/v4/letter/n/35a633/32.png) [@Nazmul](https://forums.percona.com/u/Nazmul)\
**Post date:** [March 5, 2026, 5:49pm UTC](https://forums.percona.com/t/issue-with-trigger-causing-update-errors-in-busy-node-on-galera-cluster/40337/1 "2026-03-05T17:49:33Z")

</div>

We are experiencing an issue with a trigger in our MySQL Galera Cluster. We have a table, referred to as `financial`, defined as follows:

```auto
CREATE TABLE `financial` (

 `TransactionId` int unsigned NOT NULL AUTO_INCREMENT,

 `Type` tinyint unsigned NOT NULL,

 `RecipientId` int unsigned NOT NULL,

 `RecipientSchemeId` int unsigned DEFAULT NULL,

 `PayerId` int unsigned NOT NULL,

 `PayerSchemeId` int unsigned DEFAULT NULL,

 `TransactionTimestamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',

 `Amount` decimal(10,2) NOT NULL,

 `Fees` decimal(10,2) NOT NULL,

 `Taxes` decimal(10,2) NOT NULL,

 `Status` enum('Pending','Completed','Failed','Cancelled') COLLATE utf8mb3_bin NOT NULL DEFAULT 'Pending',

 `StatusUpdated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',

 `ExternalStatus` enum('Pending','Completed','Failed','Cancelled') COLLATE utf8mb3_bin NOT NULL DEFAULT 'Pending',

 `ExternalStatusUpdated` datetime NOT NULL,

 `BatchId` int unsigned DEFAULT NULL,

 `InvoiceReference` int unsigned DEFAULT NULL,

PRIMARY KEY (`TransactionId`),

KEY `TransactionTimestamp` (`TransactionTimestamp`),

KEY `PayerSchemeId` (`PayerSchemeId`),

KEY `RecipientSchemeId` (`RecipientSchemeId`),

KEY `idx_batchid` (`BatchId`),

KEY `idx_invoice` (`InvoiceReference`),

KEY `idx_payerstatus` (`PayerId`, `Status`, `Amount`),

KEY `idx_recipientstatus` (`RecipientId`, `Status`, `Amount`),

KEY `idx_payerdate` (`PayerId`, `Status`, `TransactionTimestamp`),

KEY `idx_recipientdate` (`RecipientId`, `Status`, `TransactionTimestamp`),

KEY `idx_statusdate` (`Status`, `Type`, `TransactionTimestamp`),

KEY `idx_recipientfeestatus` (`RecipientId`, `ExternalStatus`, `Fees`)

) ENGINE=InnoDB AUTO_INCREMENT=1885796210 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin;

```

In addition, we have a trigger, named `trigger_resolv_before_insert`, set to execute before an insert operation. Its purpose is to automatically resolve and set values for `PayerSchemeId` and `RecipientSchemeId` based on other input values from the same row:

```auto
CREATE DEFINER=`root`@`localhost` TRIGGER `trigger_resolv_before_insert`

BEFORE INSERT ON `financial`

FOR EACH ROW

BEGIN

SET NEW.PayerSchemeId = func_resolve_scheme_from_account(NEW.PayerId);

SET NEW.RecipientSchemeId = func_resolve_scheme_from_account(NEW.RecipientId);

END;

```

However, when we perform an update on the `Taxes` column for a specific row with the following command:

`UPDATE financial_transaction SET Taxes = 0.05 WHERE TransactionId = 21000065445;`

we encounter the following error on one of our nodes, identified as the busy node:

**ERROR 1048 (23000): Column ‘Taxes’ cannot be null**

Interestingly, this issue occur only busy node where we have traffic and does not occur on our less busy nodes where we don’t have traffic. When we drop the trigger, the update operation works flawlessly on the busy node, indicating that the trigger might be causing the problem.

Can you please help to identify the issue why update statement triggering insert trigger.

Thanks.

---

<div class="post-metadata">

**Author:** ![Yunus](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.percona.com/yunus/32/6430_2.png) [@Yunus](https://forums.percona.com/u/Yunus)\
**Post date:** [March 6, 2026, 3:19am UTC](https://forums.percona.com/t/issue-with-trigger-causing-update-errors-in-busy-node-on-galera-cluster/40337/2 "2026-03-06T03:19:35Z")

</div>

> [@Nazmul](#):
>
> ```auto
> CREATE DEFINER=`root`@`localhost` TRIGGER `trigger_resolv_before_insert`
> 
> BEFORE INSERT ON `financial`
> 
> FOR EACH ROW
> 
> BEGIN
> 
> SET NEW.PayerSchemeId = func_resolve_scheme_from_account(NEW.PayerId);
> 
> SET NEW.RecipientSchemeId = func_resolve_scheme_from_account(NEW.RecipientId);
> 
> END;
> 
> ```

It is always better to handle the trigger from within the application instead of having it in database.

What does the function do in the trigger?

```auto
SHOW CREATE FUNCTION func_resolve_scheme_from_account;

```

That can help understand why the trigger is being called.

---

<div class="post-metadata">

**Author:** ![Nazmul](https://avatars.discourse-cdn.com/v4/letter/n/35a633/32.png) [@Nazmul](https://forums.percona.com/u/Nazmul)\
**Post date:** [March 6, 2026, 11:48am UTC](https://forums.percona.com/t/issue-with-trigger-causing-update-errors-in-busy-node-on-galera-cluster/40337/3 "2026-03-06T11:48:55Z")

</div>

> [@Yunus](#):
>
> `SHOW CREATE FUNCTION func_resolve_scheme_from_account;`

@Yunus Here is the DDL for the function and the DDL for the Procedure that called inside from the function

**Function:**

```sql
CREATE DEFINER=`user@host` FUNCTION `func_resolve_scheme_from_account`(account_id INT) RETURNS int

READS SQL DATA

BEGIN

DECLARE scheme_id INTEGER DEFAULT 0;

CALL proc_get_scheme_from_account (account_id, scheme_id);

RETURN scheme_id;

END;

```

**Stored Procedure:**

```sql
CREATE DEFINER=user@host PROCEDURE proc_get_scheme_from_account(IN account_id INT, OUT scheme_id INT)
BEGIN
DECLARE cnt INTEGER DEFAULT 0;
SELECT count(*)
FROM generic_directory – Changed table name for confidentiality
INNER JOIN account_table ON accountMemberId = generic_directoryId -- Changed table name for confidentiality
WHERE accountId = account_id
INTO cnt;

IF cnt = 0 THEN
    SET scheme_id = NULL;
ELSEIF cnt > 0 THEN
    SELECT `generic_directorySchemeId` -- Changed column name for confidentiality
    FROM `generic_directory` -- Changed table name for confidentiality
    INNER JOIN `account_table` ON `accountMemberId` = `generic_directoryId` -- Changed table name for confidentiality
    WHERE `accountId` = account_id
    INTO scheme_id;
END IF;

END;

```

I wonder why a update sql statement trigger any insert trigger.

---

<div class="post-metadata">

**Author:** ![anderson.nogueira](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.percona.com/anderson.nogueira/32/23141_2.png) [@anderson.nogueira](https://forums.percona.com/u/anderson.nogueira)\
**Post date:** [March 7, 2026, 2:52pm UTC](https://forums.percona.com/t/issue-with-trigger-causing-update-errors-in-busy-node-on-galera-cluster/40337/4 "2026-03-07T14:52:13Z")

</div>

Hi @Nazmul,

I reproduced this on a 3-node PXC 8.0.41 cluster using the schema, trigger, function, and procedure you shared. The root cause is a known MySQL server bug ([Bug #80885](https://bugs.mysql.com/bug.php?id=80885)).

When a `BEFORE INSERT` trigger fires, MySQL evaluates the row internally. If the INSERT omits a `NOT NULL` column without a `DEFAULT` (like your `Taxes DECIMAL(10,2) NOT NULL`), the server’s internal row validation state becomes stale. A subsequent `UPDATE` in the same connection then incorrectly re-validates against that stale state, producing `ERROR 1048: Column 'Taxes' cannot be null` even though the UPDATE itself sets a valid value. The trigger is not actually firing on the UPDATE; instead, leftover state from the INSERT’s trigger execution contaminates the UPDATE’s validation path.

One note: in my lab the bug reproduced consistently on both busy and idle nodes (10 out of 10 attempts on each). It is a server-level session bug, not specific to Galera replication or node load. You may be seeing it more often on busy nodes because that’s where most INSERT-then-UPDATE sequences happen in your application.

**Workarounds (all verified on PXC 8.0.41):**

The safest immediate fix is to add a `DEFAULT` to the Taxes column, which prevents the stale-state condition entirely:

```sql
ALTER TABLE financial MODIFY Taxes DECIMAL(10,2) NOT NULL DEFAULT 0.00;

```

Alternatively, include all `NOT NULL` columns explicitly in your INSERT statements (including `Taxes`), so MySQL never needs to apply implicit defaults during trigger execution.

Two other workarounds also work but are less practical: running `FLUSH TABLES` between the INSERT and UPDATE (clears the stale internal state, but has global performance impact), or adding an empty `BEFORE UPDATE` trigger (forces MySQL to re-evaluate the row properly, but adds hidden coupling).

**Fix:** Upgrade to PXC 8.0.42 or later. The upstream MySQL fix is included starting from that version. I confirmed the bug does not reproduce on PXC 8.0.45.

References:

- [MySQL Bug #80885](https://bugs.mysql.com/bug.php?id=80885)

---

<div class="post-metadata">

**Author:** ![Nazmul](https://avatars.discourse-cdn.com/v4/letter/n/35a633/32.png) [@Nazmul](https://forums.percona.com/u/Nazmul)\
**Post date:** [March 9, 2026, 10:27am UTC](https://forums.percona.com/t/issue-with-trigger-causing-update-errors-in-busy-node-on-galera-cluster/40337/5 "2026-03-09T10:27:54Z")

</div>

Hi @anderson.nogueira  
Thank you for testing the issue and sharing the bug information and solution.

Our financial table size is over 70 GB, and since MySQL [8 supports instant feature](https://dev.mysql.com/doc/refman/8.4/en/innodb-online-ddl-operations.html) for setting a column default, could you please confirm if this functionality works the same way in a Percona Galera cluster? Specifically, can we set the default value without locking the table? Our PXC version is 8.0.36-28.1

 ![image](https://us1.discourse-cdn.com/flex019/uploads/percona1/original/3X/6/6/66d1554488ea25f85e0306357ded0f1007a42f3e.png)

The command we are considering is:

`ALTER TABLE financial MODIFY Taxes DECIMAL(10,2) NOT NULL DEFAULT 0.00, ALGORITHM=INSTANT;`

Thank you for your assistance!

---

<div class="post-metadata">

**Author:** ![Yunus](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.percona.com/yunus/32/6430_2.png) [@Yunus](https://forums.percona.com/u/Yunus)\
**Post date:** [March 10, 2026, 1:57am UTC](https://forums.percona.com/t/issue-with-trigger-causing-update-errors-in-busy-node-on-galera-cluster/40337/6 "2026-03-10T01:57:12Z")

</div>

> [@Nazmul](#):
>
> ALTER TABLE financial MODIFY Taxes DECIMAL(10,2) NOT NULL DEFAULT 0.00, ALGORITHM=INSTANT;

Yes, you can use the alter table to set default value in the table using INSTANT algorithm.

It would be best to test on the test instance before running on prod.  
You can also consider using pt-online-schema-change.
