Skip to content

Commit 0389271

Browse files
author
Anna Bukatar
committed
ACP2E-963: setup:upgrade is changing indexer mode to save from schedule slowing it down immensely
1 parent 9c3a50c commit 0389271

File tree

3 files changed

+90
-18
lines changed

3 files changed

+90
-18
lines changed

lib/internal/Magento/Framework/Mview/TriggerCleaner.php

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
use Magento\Framework\App\ResourceConnection;
1111
use Magento\Framework\Mview\View\CollectionFactory;
1212
use Magento\Framework\Mview\View\StateInterface;
13+
use Magento\Framework\Mview\View\Subscription;
14+
use Magento\Framework\DB\Ddl\Trigger;
1315

1416
/**
1517
* Class for removing old triggers that were created by mview
@@ -54,28 +56,47 @@ public function __construct(
5456
*/
5557
public function removeTriggers(): bool
5658
{
59+
//Get all existing triggers from the DB
60+
$triggers = $this->getAllTriggers();
61+
$processedTriggers = [];
62+
5763
// Get list of views that are enabled
5864
$viewCollection = $this->viewCollectionFactory->create();
5965
$viewList = $viewCollection->getViewsByStateMode(StateInterface::MODE_ENABLED);
6066

61-
// Unsubscribe existing view to remove triggers from db
67+
// Check triggers declaration for the enabled views and update them if any changes
6268
foreach ($viewList as $view) {
63-
$view->unsubscribe();
69+
$subscriptions = $view->getSubscriptions();
70+
foreach ($subscriptions as $subscriptionConfig) {
71+
/* @var $subscription Subscription */
72+
$subscription = $view->initSubscriptionInstance($subscriptionConfig);
73+
$viewTriggers = $subscription->create(false)->getTriggers();
74+
foreach ($viewTriggers as $viewTrigger) {
75+
if (array_key_exists($viewTrigger->getName(), $triggers)) {
76+
foreach ($this->getStatementsFromViewTrigger($viewTrigger) as $statement) {
77+
if (!empty($statement) &&
78+
!str_contains($triggers[$viewTrigger->getName()]['ACTION_STATEMENT'],$statement)
79+
) {
80+
$subscription->saveTrigger($viewTrigger);
81+
break;
82+
}
83+
}
84+
} else {
85+
$subscription->saveTrigger($viewTrigger);
86+
}
87+
$processedTriggers[$viewTrigger->getName()] = true;
88+
}
89+
}
6490
}
6591

6692
// Remove any remaining triggers from db that are not linked to a view
67-
$triggerTableNames = $this->getTableNamesWithTriggers();
68-
foreach ($triggerTableNames as $tableName) {
69-
$view = $this->createViewByTableName($tableName);
93+
$remainingTriggers = array_diff_key($triggers, $processedTriggers);
94+
foreach ($remainingTriggers as $trigger) {
95+
$view = $this->createViewByTableName($trigger['EVENT_OBJECT_TABLE']);
7096
$view->unsubscribe();
7197
$view->getState()->delete();
7298
}
7399

74-
// Restore the previous state of the views to add triggers back to db
75-
foreach ($viewList as $view) {
76-
$view->subscribe();
77-
}
78-
79100
return true;
80101
}
81102

@@ -84,18 +105,17 @@ public function removeTriggers(): bool
84105
*
85106
* @return array
86107
*/
87-
private function getTableNamesWithTriggers(): array
108+
private function getAllTriggers(): array
88109
{
89110
$connection = $this->resource->getConnection();
90111
$dbName = $this->resource->getSchemaName(ResourceConnection::DEFAULT_CONNECTION);
91112
$sql = $connection->select()
92113
->from(
93114
['information_schema.TRIGGERS'],
94-
['EVENT_OBJECT_TABLE']
115+
['TRIGGER_NAME', 'ACTION_STATEMENT', 'EVENT_OBJECT_TABLE']
95116
)
96-
->distinct(true)
97117
->where('TRIGGER_SCHEMA = ?', $dbName);
98-
return $connection->fetchCol($sql);
118+
return $connection->fetchAssoc($sql);
99119
}
100120

101121
/**
@@ -124,4 +144,26 @@ private function createViewByTableName(string $tableName): ViewInterface
124144

125145
return $view;
126146
}
147+
148+
/**
149+
* Get trigger statements for further analyze
150+
*
151+
* @param Trigger $trigger
152+
* @return string[]
153+
*/
154+
private function getStatementsFromViewTrigger(Trigger $trigger): array
155+
{
156+
$statements = $trigger->getStatements();
157+
158+
//Check for staged entity attribute subscription
159+
$statement = array_shift($statements);
160+
if (str_contains($statement, 'SET')) {
161+
$splitStatements = explode(PHP_EOL, $statement);
162+
$statements += $splitStatements;
163+
} else {
164+
array_unshift($statements, $statement);
165+
}
166+
167+
return $statements;
168+
}
127169
}

lib/internal/Magento/Framework/Mview/View.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ public function getChangelog()
465465
* @param array $subscriptionConfig
466466
* @return SubscriptionInterface
467467
*/
468-
private function initSubscriptionInstance(array $subscriptionConfig): SubscriptionInterface
468+
public function initSubscriptionInstance(array $subscriptionConfig): SubscriptionInterface
469469
{
470470
return $this->subscriptionFactory->create(
471471
[

lib/internal/Magento/Framework/Mview/View/Subscription.php

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ class Subscription implements SubscriptionInterface
8282
*/
8383
private $mviewConfig;
8484

85+
/**
86+
* @var Trigger[]
87+
*/
88+
private $triggers = [];
89+
8590
/**
8691
* @param ResourceConnection $resource
8792
* @param TriggerFactory $triggerFactory
@@ -121,7 +126,7 @@ public function __construct(
121126
*
122127
* @return SubscriptionInterface
123128
*/
124-
public function create()
129+
public function create(bool $save = true)
125130
{
126131
foreach (Trigger::getListOfEvents() as $event) {
127132
$triggerName = $this->getAfterEventTriggerName($event);
@@ -139,14 +144,39 @@ public function create()
139144
/** @var ViewInterface $view */
140145
$trigger->addStatement($this->buildStatement($event, $view));
141146
}
147+
$this->triggers[] = $trigger;
142148

143-
$this->connection->dropTrigger($trigger->getName());
144-
$this->connection->createTrigger($trigger);
149+
if ($save) {
150+
$this->saveTrigger($trigger);
151+
}
145152
}
146153

147154
return $this;
148155
}
149156

157+
/**
158+
* Get all triggers for the subscription
159+
*
160+
* @return Trigger[]
161+
*/
162+
public function getTriggers(): array
163+
{
164+
return $this->triggers;
165+
}
166+
167+
/**
168+
* Save a trigger to the DB
169+
*
170+
* @param Trigger $trigger
171+
* @return void
172+
* @throws \Zend_Db_Exception
173+
*/
174+
public function saveTrigger(Trigger $trigger): void
175+
{
176+
$this->connection->dropTrigger($trigger->getName());
177+
$this->connection->createTrigger($trigger);
178+
}
179+
150180
/**
151181
* Remove subscription
152182
*

0 commit comments

Comments
 (0)