diff --git a/typo3/sysext/install/Classes/Updates/DatabaseRowsUpdateWizard.php b/typo3/sysext/install/Classes/Updates/DatabaseRowsUpdateWizard.php
index 4f1a4010f42b939a6ca4bd0bbed641268f2474ba..10a35e04c3cf3def954f4a87c46523a86ade96a5 100644
--- a/typo3/sysext/install/Classes/Updates/DatabaseRowsUpdateWizard.php
+++ b/typo3/sysext/install/Classes/Updates/DatabaseRowsUpdateWizard.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Updates;
 
+use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Registry;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -213,22 +214,13 @@ class DatabaseRowsUpdateWizard implements UpgradeWizardInterface, RepeatableInte
                         // Target table and sys_registry table are on the same connection, use a transaction
                         $connectionForTable->beginTransaction();
                         try {
-                            $connectionForTable->update(
+                            $this->updateOrDeleteRow(
+                                $connectionForTable,
+                                $connectionForTable,
                                 $table,
+                                (int)$rowBefore['uid'],
                                 $updatedFields,
-                                [
-                                    'uid' => $rowBefore['uid'],
-                                ]
-                            );
-                            $connectionForTable->update(
-                                'sys_registry',
-                                [
-                                    'entry_value' => serialize($startPosition),
-                                ],
-                                [
-                                    'entry_namespace' => 'installUpdateRows',
-                                    'entry_key' => 'rowUpdatePosition',
-                                ]
+                                $startPosition
                             );
                             $connectionForTable->commit();
                         } catch (\Exception $up) {
@@ -238,22 +230,13 @@ class DatabaseRowsUpdateWizard implements UpgradeWizardInterface, RepeatableInte
                     } else {
                         // Different connections for table and sys_registry -> execute two
                         // distinct queries and hope for the best.
-                        $connectionForTable->update(
+                        $this->updateOrDeleteRow(
+                            $connectionForTable,
+                            $connectionForSysRegistry,
                             $table,
+                            (int)$rowBefore['uid'],
                             $updatedFields,
-                            [
-                                'uid' => $rowBefore['uid'],
-                            ]
-                        );
-                        $connectionForSysRegistry->update(
-                            'sys_registry',
-                            [
-                                'entry_value' => serialize($startPosition),
-                            ],
-                            [
-                                'entry_namespace' => 'installUpdateRows',
-                                'entry_key' => 'rowUpdatePosition',
-                            ]
+                            $startPosition
                         );
                     }
                 }
@@ -314,4 +297,43 @@ class DatabaseRowsUpdateWizard implements UpgradeWizardInterface, RepeatableInte
         }
         return $startPosition;
     }
+
+    /**
+     * @param Connection $connectionForTable
+     * @param string $table
+     * @param array $updatedFields
+     * @param int $uid
+     * @param Connection $connectionForSysRegistry
+     * @param array $startPosition
+     */
+    protected function updateOrDeleteRow(Connection $connectionForTable, Connection $connectionForSysRegistry, string $table, int $uid, array $updatedFields, array $startPosition): void
+    {
+        $deleteField = $GLOBALS['TCA'][$table]['ctrl']['delete'] ?? null;
+        if ($deleteField === null && $updatedFields['deleted'] === 1) {
+            $connectionForTable->delete(
+                $table,
+                [
+                    'uid' => $uid,
+                ]
+            );
+        } else {
+            $connectionForTable->update(
+                $table,
+                $updatedFields,
+                [
+                    'uid' => $uid,
+                ]
+            );
+        }
+        $connectionForSysRegistry->update(
+            'sys_registry',
+            [
+                'entry_value' => serialize($startPosition),
+            ],
+            [
+                'entry_namespace' => 'installUpdateRows',
+                'entry_key' => 'rowUpdatePosition',
+            ]
+        );
+    }
 }
diff --git a/typo3/sysext/install/Classes/Updates/RowUpdater/WorkspaceVersionRecordsMigration.php b/typo3/sysext/install/Classes/Updates/RowUpdater/WorkspaceVersionRecordsMigration.php
index c58308f65d19ab2cbdec592c4c88829ed6cad76f..4da9da57596e1092efe4644b89486bdc80253282 100644
--- a/typo3/sysext/install/Classes/Updates/RowUpdater/WorkspaceVersionRecordsMigration.php
+++ b/typo3/sysext/install/Classes/Updates/RowUpdater/WorkspaceVersionRecordsMigration.php
@@ -63,7 +63,8 @@ class WorkspaceVersionRecordsMigration implements RowUpdaterInterface, LoggerAwa
         }
         // pid=-1 and live workspace => this may be very old "previous live" records that should be discarded
         if ((int)$row['t3ver_wsid'] === 0) {
-            $row['deleted'] = 1;
+            $deleteField = $GLOBALS['TCA'][$tableName]['ctrl']['delete'] ?? 'deleted';
+            $row[$deleteField] = 1;
             // continue processing versions
         }
         // regular versions and placeholders (t3ver_state one of -1, 0, 2, 4 - but not 3) having t3ver_oid set