diff --git a/vendor/magento/module-indexer/etc/crontab.xml b/vendor/magento/module-indexer/etc/crontab.xml
index 2984f47912f45..a0248a0b3b173 100644
--- a/vendor/magento/module-indexer/etc/crontab.xml
+++ b/vendor/magento/module-indexer/etc/crontab.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0"?>
 <!--
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2011 Adobe
+ * All Rights Reserved.
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
@@ -14,7 +14,7 @@
             <schedule>* * * * *</schedule>
         </job>
         <job name="indexer_clean_all_changelogs" instance="Magento\Indexer\Cron\ClearChangelog" method="execute">
-            <schedule>0 * * * *</schedule>
+            <schedule>*/5 * * * *</schedule>
         </job>
     </group>
 </config>
diff --git a/vendor/magento/module-theme/Model/Indexer/Design/IndexerHandler.php b/vendor/magento/module-theme/Model/Indexer/Design/IndexerHandler.php
index 1acc75a6c949c..5a8bf69314e2b 100644
--- a/vendor/magento/module-theme/Model/Indexer/Design/IndexerHandler.php
+++ b/vendor/magento/module-theme/Model/Indexer/Design/IndexerHandler.php
@@ -1,13 +1,14 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2020 Adobe
+ * All Rights Reserved.
  */

 declare(strict_types=1);

 namespace Magento\Theme\Model\Indexer\Design;

+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\App\ResourceConnection;
 use Magento\Framework\Indexer\IndexStructureInterface;
 use Magento\Framework\Indexer\SaveHandler\Batch;
@@ -16,6 +17,7 @@
 use Magento\Framework\Indexer\ScopeResolver\FlatScopeResolver;
 use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
 use Magento\Framework\Search\Request\Dimension;
+use Magento\Framework\Setup\Declaration\Schema\Dto\Factories\Table as DtoFactoriesTable;

 class IndexerHandler extends Grid
 {
@@ -24,6 +26,21 @@ class IndexerHandler extends Grid
      */
     private $flatScopeResolver;

+    /***
+     * check for old collation
+     */
+    private const OLDCOLLATION = 'utf8_general_ci|utf8mb3_general_ci';
+
+    /***
+     * table design_config_grid_flat
+     */
+    private const DESIGN_CONFIG_GRID_FLAT = "design_config_grid_flat";
+
+    /***
+     * @var DtoFactoriesTable
+     */
+    private $columnConfig;
+
     /**
      * @param IndexStructureInterface $indexStructure
      * @param ResourceConnection $resource
@@ -32,6 +49,7 @@ class IndexerHandler extends Grid
      * @param FlatScopeResolver $flatScopeResolver
      * @param array $data
      * @param int $batchSize
+     * @param DtoFactoriesTable|null $dtoFactoriesTable
      */
     public function __construct(
         IndexStructureInterface $indexStructure,
@@ -40,7 +58,8 @@ public function __construct(
         IndexScopeResolver $indexScopeResolver,
         FlatScopeResolver $flatScopeResolver,
         array $data,
-        $batchSize = 100
+        $batchSize = 100,
+        ?DtoFactoriesTable $dtoFactoriesTable = null
     ) {
         parent::__construct(
             $indexStructure,
@@ -51,8 +70,8 @@ public function __construct(
             $data,
             $batchSize
         );
-
         $this->flatScopeResolver = $flatScopeResolver;
+        $this->columnConfig = $dtoFactoriesTable ?: ObjectManager::getInstance()->get(DtoFactoriesTable::class);
     }

     /**
@@ -67,6 +86,27 @@ public function cleanIndex($dimensions)

         if ($this->connection->isTableExists($tableName)) {
             $this->connection->delete($tableName);
+            // change the charset to utf8mb4
+            if ($tableName === self::DESIGN_CONFIG_GRID_FLAT) {
+                $getTableSchema = $this->connection->showTableStatus($tableName) ?? '';
+                if (isset($getTableSchema['Collation']) &&
+                    preg_match('/\b('. self::OLDCOLLATION .')\b/', $getTableSchema['Collation'])) {
+                    $charset = $this->columnConfig->getDefaultCharset();
+                    $collate = $this->columnConfig->getDefaultCollation();
+                    $columnEncoding = " CHARACTER SET ".$charset." COLLATE ".$collate;
+                    $this->connection->query(
+                        sprintf(
+                            'ALTER TABLE `%s` MODIFY COLUMN `theme_theme_id` varchar(255) %s %s,
+                             DEFAULT CHARSET=%s, DEFAULT COLLATE=%s',
+                            $tableName,
+                            $columnEncoding,
+                            "COMMENT 'Theme_theme_id'",
+                            $charset,
+                            $collate
+                        )
+                    );
+                }
+            }
         } else {
             $this->indexStructure->create($this->getIndexName(), $this->fields, $dimensions);
         }
diff --git a/vendor/magento/framework/DB/Adapter/Pdo/Mysql.php b/vendor/magento/framework/DB/Adapter/Pdo/Mysql.php
index fc84dcafc4688..beeadf1623f77 100644
--- a/vendor/magento/framework/DB/Adapter/Pdo/Mysql.php
+++ b/vendor/magento/framework/DB/Adapter/Pdo/Mysql.php
@@ -1,7 +1,7 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2014 Adobe
+ * All Rights Reserved.
  */

 namespace Magento\Framework\DB\Adapter\Pdo;
@@ -32,6 +32,7 @@
 use Magento\Framework\Stdlib\StringUtils;
 use Zend_Db_Adapter_Exception;
 use Zend_Db_Statement_Exception;
+use Magento\Framework\Setup\Declaration\Schema\Dto\Factories\Table as DtoFactoriesTable;

 // @codingStandardsIgnoreStart

@@ -144,6 +145,11 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface, Rese
      */
     private $isMysql8Engine;

+    /***
+     * const for column type
+     */
+    private const COLUMN_TYPE = ['varchar', 'char', 'text', 'mediumtext', 'longtext'];
+
     /**
      * MySQL column - Table DDL type pairs
      *
@@ -251,6 +257,11 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface, Rese
      */
     private $parentConnections = [];

+    /***
+     * @var DtoFactoriesTable
+     */
+    private $columnConfig;
+
     /**
      * Constructor
      *
@@ -260,6 +271,7 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface, Rese
      * @param SelectFactory $selectFactory
      * @param array $config
      * @param SerializerInterface|null $serializer
+     * @param DtoFactoriesTable|null $dtoFactoriesTable
      */
     public function __construct(
         StringUtils $string,
@@ -267,13 +279,15 @@ public function __construct(
         LoggerInterface $logger,
         SelectFactory $selectFactory,
         array $config = [],
-        SerializerInterface $serializer = null
+        SerializerInterface $serializer = null,
+        ?DtoFactoriesTable $dtoFactoriesTable = null
     ) {
         $this->pid = getmypid();
         $this->string = $string;
         $this->dateTime = $dateTime;
         $this->logger = $logger;
         $this->selectFactory = $selectFactory;
+        $this->columnConfig = $dtoFactoriesTable ?: ObjectManager::getInstance()->get(DtoFactoriesTable::class);
         $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
         $this->exceptionMap = [
             // SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
@@ -1240,7 +1254,11 @@ public function modifyColumn($tableName, $columnName, $definition, $flushData =
         if (is_array($definition)) {
             $definition = $this->_getColumnDefinition($definition);
         }
-
+        // Set default collation to utf8mb4 for MySQL
+        if (!empty($definition)) {
+            $type = explode(' ', trim($definition));
+            $definition = $this->setDefaultCharsetAndCollation($type[0], $definition, 1);
+        }
         $sql = sprintf(
             'ALTER TABLE %s MODIFY COLUMN %s %s',
             $this->quoteIdentifier($tableName),
@@ -2404,7 +2422,13 @@ protected function _getColumnsDefinition(Table $table)
                 $columnDefinition
             );
         }
-
+        // Set default collation to utf8mb4 for MySQL
+        if (count($definition)) {
+            foreach ($definition as $index => $columnDefinition) {
+                $type = explode(' ', trim($columnDefinition));
+                $definition[$index] = $this->setDefaultCharsetAndCollation($type[1], $columnDefinition, 2);
+            }
+        }
         // PRIMARY KEY
         if (!empty($primary)) {
             asort($primary, SORT_NUMERIC);
@@ -4249,4 +4273,26 @@ public function __debugInfo()
     {
         return [];
     }
+
+    /***
+     * Set default collation & charset (e.g.utf8mb4_general_ci and utf8mb4) for tables
+     *
+     * @param string $columnType
+     * @param string $definition
+     * @param int $position
+     * @return string
+     */
+    private function setDefaultCharsetAndCollation($columnType, $definition, $position) : string
+    {
+        $pattern = '/\b(' . implode('|', array_map('preg_quote', self::COLUMN_TYPE)) . ')\b/i';
+        if (preg_match($pattern, $columnType) === 1) {
+            $charset = $this->columnConfig->getDefaultCharset();
+            $collate = $this->columnConfig->getDefaultCollation();
+            $charsets = 'CHARACTER SET ' . $charset. ' COLLATE ' . $collate;
+            $columnsAttribute = explode(' ', trim($definition));
+            array_splice($columnsAttribute, $position, 0, $charsets);
+            return implode(' ', $columnsAttribute);
+        }
+        return $definition;
+    }
 }
diff --git a/vendor/magento/framework/DB/Ddl/Table.php b/vendor/magento/framework/DB/Ddl/Table.php
index 5ba54368c188d..45c9c1c6f0de6 100644
--- a/vendor/magento/framework/DB/Ddl/Table.php
+++ b/vendor/magento/framework/DB/Ddl/Table.php
@@ -1,11 +1,13 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2014 Adobe
+ * All Rights Reserved.
  */
 namespace Magento\Framework\DB\Ddl;

 use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Framework\Setup\Declaration\Schema\Dto\Factories\Table as DtoTable;
+use Magento\Framework\App\ObjectManager;

 /**
  * Data Definition for table
@@ -237,6 +239,22 @@ class Table
      */
     protected $_options = ['type' => 'INNODB', 'charset' => 'utf8', 'collate' => 'utf8_general_ci'];

+    /***
+     * @var DtoTable|null
+     */
+    private ?DtoTable $DtoTable;
+
+    /***
+     * constructor
+     *
+     * @param DtoTable|null $DtoTable
+     */
+    public function __construct(
+        ?DtoTable $DtoTable = null
+    ) {
+        $this->DtoTable = $DtoTable ?: ObjectManager::getInstance()->get(DtoTable::class);
+    }
+
     /**
      * Set table name
      *
@@ -636,7 +654,7 @@ public function setOption($key, $value)
     /**
      * Retrieve table option value by option name
      *
-     * Return null if option does not exits
+     * Return null if option does not exist
      *
      * @param string $key
      * @return null|string
@@ -646,6 +664,12 @@ public function getOption($key)
         if (!isset($this->_options[$key])) {
             return null;
         }
+        if (strtolower($key) == 'charset') {
+            return $this->DtoTable->getDefaultCharset();
+        }
+        if (strtolower($key) == 'collate') {
+            return $this->DtoTable->getDefaultCollation();
+        }
         return $this->_options[$key];
     }

diff --git a/vendor/magento/framework/Mview/View/Changelog.php b/vendor/magento/framework/Mview/View/Changelog.php
index c7529a69d2fc6..15f1e78866bff 100644
--- a/vendor/magento/framework/Mview/View/Changelog.php
+++ b/vendor/magento/framework/Mview/View/Changelog.php
@@ -1,21 +1,23 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2014 Adobe
+ * All Rights Reserved.
  */

 namespace Magento\Framework\Mview\View;

 use Magento\Framework\App\ObjectManager;
 use Magento\Framework\DB\Adapter\ConnectionException;
-use Magento\Framework\DB\Sql\Expression;
 use Magento\Framework\Exception\RuntimeException;
 use Magento\Framework\Mview\Config;
 use Magento\Framework\Mview\View\AdditionalColumnsProcessor\ProcessorFactory;
+use Magento\Framework\Setup\Declaration\Schema\Dto\Factories\Table as DtoFactoriesTable;
 use Magento\Framework\Phrase;

 /**
  * Class Changelog for manipulations with the mview_state table.
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Changelog implements ChangelogInterface
 {
@@ -34,6 +36,11 @@ class Changelog implements ChangelogInterface
      */
     public const VERSION_ID_COLUMN_NAME = 'version_id';

+    /**
+     * Batch size for changelog cleaning operation
+     */
+    private const CHANGELOG_CLEAR_BATCH_SIZE = 10000;
+
     /**
      * Database connection
      *
@@ -63,22 +70,37 @@ class Changelog implements ChangelogInterface
      */
     private $additionalColumnsProcessorFactory;

+    /***
+     * Old Charset for cl tables
+     */
+    private const OLDCHARSET = 'utf8|utf8mb3';
+
+    /***
+     * @var DtoFactoriesTable|null
+     */
+    private $columnConfig;
+
     /**
      * @param \Magento\Framework\App\ResourceConnection $resource
      * @param Config $mviewConfig
      * @param ProcessorFactory $additionalColumnsProcessorFactory
+     * @param DtoFactoriesTable|null $dtoFactoriesTable
+     * @param int $batchSize
      * @throws ConnectionException
      */
     public function __construct(
         \Magento\Framework\App\ResourceConnection $resource,
         Config $mviewConfig,
-        ProcessorFactory $additionalColumnsProcessorFactory
+        ProcessorFactory $additionalColumnsProcessorFactory,
+        ?DtoFactoriesTable $dtoFactoriesTable = null,
+        private readonly int $batchSize = self::CHANGELOG_CLEAR_BATCH_SIZE,
     ) {
         $this->connection = $resource->getConnection();
         $this->resource = $resource;
         $this->checkConnection();
         $this->mviewConfig = $mviewConfig;
         $this->additionalColumnsProcessorFactory = $additionalColumnsProcessorFactory;
+        $this->columnConfig = $dtoFactoriesTable ?: ObjectManager::getInstance()->get(DtoFactoriesTable::class);
     }

     /**
@@ -130,6 +152,21 @@ public function create()
             }

             $this->connection->createTable($table);
+        } else {
+            // change the charset to utf8mb4
+            $getTableSchema = $this->connection->getCreateTable($changelogTableName) ?? '';
+            if (preg_match('/\b('. self::OLDCHARSET .')\b/', $getTableSchema)) {
+                $charset = $this->columnConfig->getDefaultCharset();
+                $collate = $this->columnConfig->getDefaultCollation();
+                $this->connection->query(
+                    sprintf(
+                        'ALTER TABLE %s DEFAULT CHARSET=%s, DEFAULT COLLATE=%s',
+                        $changelogTableName,
+                        $charset,
+                        $collate
+                    )
+                );
+            }
         }
     }

@@ -191,7 +228,15 @@ public function clear($versionId)
             throw new ChangelogTableNotExistsException(new Phrase("Table %1 does not exist", [$changelogTableName]));
         }

-        $this->connection->delete($changelogTableName, ['version_id < ?' => (int)$versionId]);
+        $query = sprintf(
+            'DELETE FROM `%s` WHERE %s LIMIT %d',
+            $changelogTableName,
+            'version_id < ' . (int) $versionId,
+            $this->batchSize
+        );
+        do {
+            $stmt = $this->connection->query($query);
+        } while ($stmt->rowCount());

         return true;
     }
diff --git a/vendor/magento/framework/Setup/Declaration/Schema/Db/MySQL/DbSchemaReader.php b/vendor/magento/framework/Setup/Declaration/Schema/Db/MySQL/DbSchemaReader.php
index d8c85ea9e206d..321dbe3ff44fb 100644
--- a/vendor/magento/framework/Setup/Declaration/Schema/Db/MySQL/DbSchemaReader.php
+++ b/vendor/magento/framework/Setup/Declaration/Schema/Db/MySQL/DbSchemaReader.php
@@ -1,7 +1,7 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2017 Adobe
+ * All Rights Reserved.
  */
 declare(strict_types=1);

@@ -21,7 +21,7 @@ class DbSchemaReader implements DbSchemaReaderInterface
     /**
      * Table type in information_schema.TABLES which allows to identify only tables and ignore views
      */
-    const MYSQL_TABLE_TYPE = 'BASE TABLE';
+    public const MYSQL_TABLE_TYPE = 'BASE TABLE';

     /**
      * @var ResourceConnection
@@ -54,6 +54,17 @@ public function getTableOptions($tableName, $resource)
     {
         $adapter = $this->resourceConnection->getConnection($resource);
         $dbName = $this->resourceConnection->getSchemaName($resource);
+        $collationNameColumn = 'charset_applicability.collation_name';
+
+        /* In case of mariadb>=11.4 check if column FULL_COLLATION_NAME is exist */
+        if ($adapter->tableColumnExists(
+            'COLLATION_CHARACTER_SET_APPLICABILITY',
+            'FULL_COLLATION_NAME',
+            'information_schema'
+        )) {
+            $collationNameColumn = 'charset_applicability.full_collation_name';
+        }
+
         $stmt = $adapter->select()
             ->from(
                 ['i_tables' => 'information_schema.TABLES'],
@@ -65,7 +76,7 @@ public function getTableOptions($tableName, $resource)
             )
             ->joinInner(
                 ['charset_applicability' => 'information_schema.COLLATION_CHARACTER_SET_APPLICABILITY'],
-                'i_tables.table_collation = charset_applicability.collation_name',
+                'i_tables.table_collation = '.$collationNameColumn,
                 [
                     'charset' => 'charset_applicability.CHARACTER_SET_NAME'
                 ]
@@ -98,7 +109,9 @@ public function readColumns($tableName, $resource)
                     'nullable' => new Expression('IF(IS_NULLABLE="YES", true, false)'),
                     'definition' => 'COLUMN_TYPE',
                     'extra' => 'EXTRA',
-                    'comment' => new Expression('IF(COLUMN_COMMENT="", NULL, COLUMN_COMMENT)')
+                    'comment' => new Expression('IF(COLUMN_COMMENT="", NULL, COLUMN_COMMENT)'),
+                    'charset' => 'CHARACTER_SET_NAME',
+                    'collation' => 'COLLATION_NAME'
                 ]
             )
             ->where('TABLE_SCHEMA = ?', $dbName)
diff --git a/vendor/magento/framework/Setup/Declaration/Schema/Db/MySQL/DbSchemaWriter.php b/vendor/magento/framework/Setup/Declaration/Schema/Db/MySQL/DbSchemaWriter.php
index b466eae77d9e2..ead0de2d667f5 100644
--- a/vendor/magento/framework/Setup/Declaration/Schema/Db/MySQL/DbSchemaWriter.php
+++ b/vendor/magento/framework/Setup/Declaration/Schema/Db/MySQL/DbSchemaWriter.php
@@ -1,12 +1,17 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2017 Adobe
+ * All Rights Reserved.
  */
+declare(strict_types=1);

 namespace Magento\Framework\Setup\Declaration\Schema\Db\MySQL;

 use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\DB\Adapter\ConnectionException;
+use Magento\Framework\DB\Adapter\SqlVersionProvider;
+use Magento\Framework\DB\Adapter\AdapterInterface;
 use Magento\Framework\Setup\Declaration\Schema\Db\DbSchemaWriterInterface;
 use Magento\Framework\Setup\Declaration\Schema\Db\Statement;
 use Magento\Framework\Setup\Declaration\Schema\Db\StatementAggregator;
@@ -15,9 +20,12 @@
 use Magento\Framework\Setup\Declaration\Schema\Dto\Constraint;
 use Magento\Framework\Setup\Declaration\Schema\Dto\Constraints\Reference;
 use Magento\Framework\Setup\Declaration\Schema\DryRunLogger;
+use Magento\Framework\Setup\Declaration\Schema\Dto\Factories\Table as DtoFactoriesTable;

 /**
  * @inheritdoc
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class DbSchemaWriter implements DbSchemaWriterInterface
 {
@@ -59,22 +67,40 @@ class DbSchemaWriter implements DbSchemaWriterInterface
      */
     private $dryRunLogger;

+    /**
+     * @var SqlVersionProvider
+     */
+    private $sqlVersionProvider;
+
+    /***
+     * @var DtoFactoriesTable
+     */
+    private DtoFactoriesTable $columnConfig;
+
+    private const COLUMN_TYPE = ['varchar', 'char', 'text', 'mediumtext', 'longtext'];
+
     /**
      * @param ResourceConnection $resourceConnection
-     * @param StatementFactory   $statementFactory
-     * @param DryRunLogger       $dryRunLogger
-     * @param array              $tableOptions
+     * @param StatementFactory $statementFactory
+     * @param DryRunLogger $dryRunLogger
+     * @param SqlVersionProvider $sqlVersionProvider
+     * @param DtoFactoriesTable|null $dtoFactoriesTable
+     * @param array $tableOptions
      */
     public function __construct(
         ResourceConnection $resourceConnection,
         StatementFactory $statementFactory,
         DryRunLogger $dryRunLogger,
+        SqlVersionProvider $sqlVersionProvider,
+        ?DtoFactoriesTable $dtoFactoriesTable = null,
         array $tableOptions = []
     ) {
         $this->resourceConnection = $resourceConnection;
         $this->statementFactory = $statementFactory;
         $this->dryRunLogger = $dryRunLogger;
+        $this->columnConfig = $dtoFactoriesTable ?: ObjectManager::getInstance()->get(DtoFactoriesTable::class);
         $this->tableOptions = array_replace($this->tableOptions, $tableOptions);
+        $this->sqlVersionProvider = $sqlVersionProvider;
     }

     /**
@@ -82,6 +108,15 @@ public function __construct(
      */
     public function createTable($tableName, $resource, array $definition, array $options)
     {
+        if (count($definition)) {
+            foreach ($definition as $index => $value) {
+                if ($this->isColumnExists($value, self::COLUMN_TYPE)) {
+                    if (str_contains($index, 'column')) {
+                        $definition[$index] = $this->setDefaultCharsetAndCollation($value);
+                    }
+                }
+            }
+        }
         $sql = sprintf(
             "(\n%s\n) ENGINE=%s DEFAULT CHARSET=%s DEFAULT COLLATE=%s %s",
             implode(", \n", $definition),
@@ -202,6 +237,10 @@ public function modifyTableOption($tableName, $resource, $optionName, $optionVal
      */
     public function modifyColumn($columnName, $resource, $tableName, $columnDefinition)
     {
+        if ($this->isColumnExists($columnDefinition, self::COLUMN_TYPE)) {
+            $columnDefinition = $this->setDefaultCharsetAndCollation($columnDefinition);
+        }
+
         $sql = sprintf(
             'MODIFY COLUMN %s',
             $columnDefinition
@@ -271,15 +310,14 @@ public function compile(StatementAggregator $statementAggregator, $dryRun)
             $statementsSql = [];
             $statement = null;

-            /**
-             * @var Statement $statement
-             */
-            foreach ($statementBank as $statement) {
-                $statementsSql[] = $statement->getStatement();
-            }
-            $adapter = $this->resourceConnection->getConnection($statement->getResource());
-
             if ($dryRun) {
+                /**
+                 * @var Statement $statement
+                 */
+                foreach ($statementBank as $statement) {
+                    $statementsSql[] = $statement->getStatement();
+                }
+                $adapter = $this->resourceConnection->getConnection($statement->getResource());
                 $this->dryRunLogger->log(
                     sprintf(
                         $this->statementDirectives[$statement->getType()],
@@ -288,18 +326,82 @@ public function compile(StatementAggregator $statementAggregator, $dryRun)
                     )
                 );
             } else {
+                $this->doQuery($statementBank);
+                $statement = end($statementBank);
+                //Do post update, like SQL DML operations or etc...
+                foreach ($statement->getTriggers() as $trigger) {
+                    call_user_func($trigger);
+                }
+            }
+        }
+    }
+
+    /**
+     * Check if we can concatenate sql into one statement
+     *
+     * Due to issues with some versions of MariaBD such statements
+     * may produce errors, e.g. with foreign key definition with column modification
+     *
+     * @return bool
+     * @throws ConnectionException
+     */
+    private function isNeedToSplitSql() : bool
+    {
+        return str_contains($this->sqlVersionProvider->getSqlVersion(), SqlVersionProvider::MARIA_DB_10_4_VERSION) ||
+            str_contains($this->sqlVersionProvider->getSqlVersion(), SqlVersionProvider::MARIA_DB_10_6_VERSION) ||
+            str_contains($this->sqlVersionProvider->getSqlVersion(), SqlVersionProvider::MARIA_DB_11_4_VERSION);
+    }
+
+    /**
+     * Perform queries based on statements
+     *
+     * @param Statement[] $statementBank
+     * @return void
+     * @throws ConnectionException
+     */
+    private function doQuery(
+        array $statementBank
+    ) : void {
+        if (empty($statementBank)) {
+            return;
+        }
+
+        $statement = null;
+        $statementsSql = [];
+        foreach ($statementBank as $statement) {
+            $statementsSql[] = $statement->getStatement();
+        }
+        $adapter = $this->resourceConnection->getConnection($statement->getResource());
+
+        if ($this->isNeedToSplitSql()) {
+            $preparedStatements = $this->getPreparedStatements($statementBank);
+
+            if (!empty($preparedStatements['canBeCombinedStatements'])) {
                 $adapter->query(
                     sprintf(
                         $this->statementDirectives[$statement->getType()],
                         $adapter->quoteIdentifier($statement->getTableName()),
-                        implode(", ", $statementsSql)
+                        implode(", ", $preparedStatements['canBeCombinedStatements'])
                     )
                 );
-                //Do post update, like SQL DML operations or etc...
-                foreach ($statement->getTriggers() as $trigger) {
-                    call_user_func($trigger);
-                }
             }
+            foreach ($preparedStatements['separatedStatements'] as $separatedStatement) {
+                $adapter->query(
+                    sprintf(
+                        $this->statementDirectives[$statement->getType()],
+                        $adapter->quoteIdentifier($statement->getTableName()),
+                        $separatedStatement
+                    )
+                );
+            }
+        } else {
+            $adapter->query(
+                sprintf(
+                    $this->statementDirectives[$statement->getType()],
+                    $adapter->quoteIdentifier($statement->getTableName()),
+                    implode(", ", $statementsSql)
+                )
+            );
         }
     }

@@ -309,6 +411,7 @@ public function compile(StatementAggregator $statementAggregator, $dryRun)
      * @param string $tableName
      * @param string $resource
      * @return int
+     * @throws \Zend_Db_Statement_Exception
      */
     private function getNextAutoIncrementValue(string $tableName, string $resource): int
     {
@@ -323,6 +426,89 @@ private function getNextAutoIncrementValue(string $tableName, string $resource):
         } else {
             return 1;
         }
+    }
+
+    /**
+     * Prepare list of modified columns from statement
+     *
+     * @param array $statementBank
+     * @return array
+     */
+    private function getModifiedColumns(array $statementBank) : array
+    {
+        $columns = [];
+        foreach ($statementBank as $statement) {
+            if ($statement->getType() === 'alter'
+                && str_contains($statement->getStatement(), 'MODIFY COLUMN')) {
+                $columns[] = $statement->getName();
+            }
+        }
+        return $columns;
+    }
+
+    /**
+     * Separate statements that can't be executed as one statement
+     *
+     * @param array $statementBank
+     * @return array
+     */
+    private function getPreparedStatements(array $statementBank) : array
+    {
+        $statementsSql = [];
+        foreach ($statementBank as $statement) {
+            $statementsSql[] = $statement->getStatement();
+        }
+        $result = ['separatedStatements' => [], 'canBeCombinedStatements' => []];
+        $modifiedColumns = $this->getModifiedColumns($statementBank);

+        foreach ($statementsSql as $statementSql) {
+            if (str_contains($statementSql, 'FOREIGN KEY')) {
+                $isThisColumnModified = false;
+                foreach ($modifiedColumns as $modifiedColumn) {
+                    if (str_contains($statementSql, '`' . $modifiedColumn . '`')) {
+                        $isThisColumnModified = true;
+                        break;
+                    }
+                }
+                if ($isThisColumnModified) {
+                    $result['separatedStatements'][] = $statementSql;
+                } else {
+                    $result['canBeCombinedStatements'][] = $statementSql;
+                }
+            } else {
+                $result['canBeCombinedStatements'][] = $statementSql;
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * Set default collation & charset (e.g. utf8mb4_general_ci and utf8mb4) for tables
+     *
+     * @param string $columnDefinition
+     * @return string
+     */
+    private function setDefaultCharsetAndCollation(string $columnDefinition): string
+    {
+        $charset = $this->columnConfig->getDefaultCharset();
+        $collate = $this->columnConfig->getDefaultCollation();
+        $columnLevelConfig = 'CHARACTER SET ' . $charset . ' COLLATE ' . $collate;
+        $columnsAttribute  = explode(' ', $columnDefinition);
+        array_splice($columnsAttribute, 2, 0, $columnLevelConfig);
+        return implode(" ", $columnsAttribute);
+    }
+
+    /**
+     * Checks if any column of type varchar,char or text (mediumtext/longtext)
+     *
+     * @param string $definition
+     * @param array $columntypes
+     * @return bool
+     */
+    private function isColumnExists(string $definition, array $columntypes): bool
+    {
+        $type = explode(' ', $definition);
+        $pattern = '/\b(' . implode('|', array_map('preg_quote', $columntypes)) . ')\b/i';
+        return preg_match($pattern, $type[1]) === 1;
     }
 }
diff --git a/vendor/magento/framework/Setup/Declaration/Schema/Dto/Columns/StringBinary.php b/vendor/magento/framework/Setup/Declaration/Schema/Dto/Columns/StringBinary.php
index 4de198ae631f4..e8c2fbe0f6eab 100644
--- a/vendor/magento/framework/Setup/Declaration/Schema/Dto/Columns/StringBinary.php
+++ b/vendor/magento/framework/Setup/Declaration/Schema/Dto/Columns/StringBinary.php
@@ -1,7 +1,7 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2017 Adobe
+ * All Rights Reserved.
  */
 namespace Magento\Framework\Setup\Declaration\Schema\Dto\Columns;

@@ -34,6 +34,16 @@ class StringBinary extends Column implements
      */
     private $length;

+    /**
+     * @var string|null
+     */
+    private $charset;
+
+    /**
+     * @var string|null
+     */
+    private $collation;
+
     /**
      * Constructor.
      *
@@ -45,6 +55,10 @@ class StringBinary extends Column implements
      * @param string $default
      * @param string|null $comment
      * @param string|null $onCreate
+     * @param string|null $charset
+     * @param string|null $collation
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
         string $name,
@@ -54,12 +68,16 @@ public function __construct(
         bool $nullable = true,
         string $default = null,
         string $comment = null,
-        string $onCreate = null
+        string $onCreate = null,
+        ?string $charset = 'utf8mb4',
+        ?string $collation = 'utf8mb4_general_ci'
     ) {
         parent::__construct($name, $type, $table, $comment, $onCreate);
         $this->nullable = $nullable;
         $this->default = $default;
         $this->length = $length;
+        $this->charset = $charset;
+        $this->collation = $collation;
     }

     /**
@@ -92,17 +110,42 @@ public function getLength()
         return $this->length;
     }

+    /**
+     * Get collation
+     *
+     * @return string|null
+     */
+    public function getCollation(): ?string
+    {
+        return $this->collation;
+    }
+
+    /**
+     * Get charset
+     *
+     * @return string|null
+     */
+    public function getCharset(): ?string
+    {
+        return $this->charset;
+    }
+
     /**
      * @inheritdoc
      */
     public function getDiffSensitiveParams()
     {
-        return [
+        $param = [
             'type' => $this->getType(),
             'nullable' => $this->isNullable(),
             'default' => $this->getDefault(),
             'length' => $this->getLength(),
             'comment' => $this->getComment()
         ];
+        if ($this->getType() === 'varchar') {
+            $param['collation'] = $this->getCollation();
+            $param['charset'] = $this->getCharset();
+        }
+        return $param;
     }
 }
diff --git a/vendor/magento/framework/Setup/Declaration/Schema/Dto/Columns/Text.php b/vendor/magento/framework/Setup/Declaration/Schema/Dto/Columns/Text.php
index b127d5d50e08c..750027490c470 100644
--- a/vendor/magento/framework/Setup/Declaration/Schema/Dto/Columns/Text.php
+++ b/vendor/magento/framework/Setup/Declaration/Schema/Dto/Columns/Text.php
@@ -1,7 +1,7 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2017 Adobe
+ * All Rights Reserved.
  */
 namespace Magento\Framework\Setup\Declaration\Schema\Dto\Columns;

@@ -22,6 +22,16 @@ class Text extends Column implements
      */
     private $nullable;

+    /**
+     * @var string|null
+     */
+    private $charset;
+
+    /**
+     * @var string|null
+     */
+    private $collation;
+
     /**
      * Constructor.
      *
@@ -31,6 +41,8 @@ class Text extends Column implements
      * @param bool $nullable
      * @param string|null $comment
      * @param string|null $onCreate
+     * @param string|null $charset
+     * @param string|null $collation
      */
     public function __construct(
         string $name,
@@ -38,10 +50,14 @@ public function __construct(
         Table $table,
         bool $nullable = true,
         string $comment = null,
-        string $onCreate = null
+        string $onCreate = null,
+        ?string $charset = 'utf8mb4',
+        ?string $collation = 'utf8mb4_general_ci'
     ) {
         parent::__construct($name, $type, $table, $comment, $onCreate);
         $this->nullable = $nullable;
+        $this->charset = $charset;
+        $this->collation = $collation;
     }

     /**
@@ -54,6 +70,26 @@ public function isNullable()
         return $this->nullable;
     }

+    /**
+     * Get collation
+     *
+     * @return string|null
+     */
+    public function getCollation(): ?string
+    {
+        return $this->collation;
+    }
+
+    /**
+     * Get charset
+     *
+     * @return string|null
+     */
+    public function getCharset(): ?string
+    {
+        return $this->charset;
+    }
+
     /**
      * @inheritdoc
      */
@@ -62,7 +98,9 @@ public function getDiffSensitiveParams()
         return [
             'type' => $this->getType(),
             'nullable' => $this->isNullable(),
-            'comment' => $this->getComment()
+            'comment' => $this->getComment(),
+            'collation' => $this->getCollation(),
+            'charset' => $this->getCharset()
         ];
     }
 }
diff --git a/vendor/magento/framework/Setup/Declaration/Schema/Dto/Factories/Table.php b/vendor/magento/framework/Setup/Declaration/Schema/Dto/Factories/Table.php
index 3fde8398fccf8..86e980b52ced9 100644
--- a/vendor/magento/framework/Setup/Declaration/Schema/Dto/Factories/Table.php
+++ b/vendor/magento/framework/Setup/Declaration/Schema/Dto/Factories/Table.php
@@ -1,7 +1,7 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2017 Adobe
+ * All Rights Reserved.
  */

 namespace Magento\Framework\Setup\Declaration\Schema\Dto\Factories;
@@ -48,10 +48,10 @@ class Table implements FactoryInterface
      * @var array|string[]
      */
     private static array $defaultCharset = [
-        '10.4.' => 'utf8',
-        '10.6.' => 'utf8mb3',
-        '10.11.' => 'utf8mb3',
-        'mysql_8_29' => 'utf8mb3',
+        '10.4.' => 'utf8mb4',
+        '10.6.' => 'utf8mb4',
+        '11.4.' => 'utf8mb4',
+        'mysql_8_29' => 'utf8mb4',
         'default' => 'utf8'
     ];

@@ -59,10 +59,10 @@ class Table implements FactoryInterface
      * @var array|string[]
      */
     private static array $defaultCollation = [
-        '10.4.' => 'utf8_general_ci',
-        '10.6.' => 'utf8mb3_general_ci',
-        '10.11.' => 'utf8mb3_general_ci',
-        'mysql_8_29' => 'utf8mb3_general_ci',
+        '10.4.' => 'utf8mb4_general_ci',
+        '10.6.' => 'utf8mb4_general_ci',
+        '11.4.' => 'utf8mb4_general_ci',
+        'mysql_8_29' => 'utf8mb4_general_ci',
         'default' => 'utf8_general_ci'
     ];

@@ -124,7 +124,7 @@ public function create(array $data)
      *
      * @return string
      */
-    private function getDefaultCharset(): string
+    public function getDefaultCharset(): string
     {
         if ($this->sqlVersionProvider->isMysqlGte8029()) {
             return self::$defaultCharset['mysql_8_29'];
@@ -139,7 +139,7 @@ private function getDefaultCharset(): string
      *
      * @return string
      */
-    private function getDefaultCollation(): string
+    public function getDefaultCollation(): string
     {
         if ($this->sqlVersionProvider->isMysqlGte8029()) {
             return self::$defaultCollation['mysql_8_29'];
diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php
index 67bb890cce77e..8ca000ff61da0 100644
--- a/setup/src/Magento/Setup/Model/Installer.php
+++ b/setup/src/Magento/Setup/Model/Installer.php
@@ -1,7 +1,7 @@
 <?php
 /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
+ * Copyright 2015 Adobe
+ * All Rights Reserved.
  */

 namespace Magento\Setup\Model;
@@ -60,6 +60,7 @@
 use Magento\Store\Model\Store;
 use Magento\RemoteStorage\Setup\ConfigOptionsList as RemoteStorageValidator;
 use ReflectionException;
+use Magento\Framework\Setup\Declaration\Schema\Dto\Factories\Table as DtoFactoriesTable;

 /**
  * Class Installer contains the logic to install Magento application.
@@ -259,6 +260,16 @@ class Installer
      */
     private $triggerCleaner;

+    /***
+     * Old Charset for cl tables
+     */
+    private const OLDCHARSET = 'utf8|utf8mb3';
+
+    /***
+     * @var DtoFactoriesTable
+     */
+    private $columnConfig;
+
     /**
      * Constructor
      *
@@ -283,6 +294,7 @@ class Installer
      * @param State $sampleDataState
      * @param ComponentRegistrar $componentRegistrar
      * @param PhpReadinessCheck $phpReadinessCheck
+     * @param DtoFactoriesTable|null $dtoFactoriesTable
      * @throws Exception
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
@@ -307,7 +319,8 @@ public function __construct(
         DataSetupFactory $dataSetupFactory,
         State $sampleDataState,
         ComponentRegistrar $componentRegistrar,
-        PhpReadinessCheck $phpReadinessCheck
+        PhpReadinessCheck $phpReadinessCheck,
+        ?DtoFactoriesTable $dtoFactoriesTable = null
     ) {
         $this->filePermissions = $filePermissions;
         $this->deploymentConfigWriter = $deploymentConfigWriter;
@@ -338,6 +351,8 @@ public function __construct(
          * from that ObjectManager gets reset as different steps in the installer will write to the deployment config.
          */
         $this->firstDeploymentConfig = ObjectManager::getInstance()->get(DeploymentConfig::class);
+        $this->columnConfig = $dtoFactoriesTable ?: ObjectManager::getInstance()->get(DtoFactoriesTable::class);
+        ;
     }

     /**
@@ -644,6 +659,16 @@ private function setupModuleRegistry(SchemaSetupInterface $setup)
                     'Data Version'
                 )->setComment('Module versions registry');
             $connection->createTable($table);
+        } else {
+            // Set default collation to utf8mb4 for MySQL
+            $getTableSchema = $connection->getCreateTable($setup->getTable('setup_module')) ?? '';
+            if (preg_match('/\b('. self::OLDCHARSET .')\b/', $getTableSchema)) {
+                $tableName = $setup->getTable('setup_module');
+                $columns = ['module' => ['varchar(50)',''],
+                            'schema_version' => ['varchar(50)',''],
+                            'data_version' => ['varchar(50)','']];
+                $this->setDefaultCharsetAndCollation($tableName, $columns, $connection);
+            }
         }
     }

@@ -703,6 +728,14 @@ private function setupSessionTable(
                 'Database Sessions Storage'
             );
             $connection->createTable($table);
+        } else {
+            // Set default collation to utf8mb4 for MySQL
+            $getTableSchema = $connection->getCreateTable($setup->getTable('session')) ?? '';
+            if (preg_match('/\b('. self::OLDCHARSET .')\b/', $getTableSchema)) {
+                $tableName = $setup->getTable('session');
+                $columns = ['session_id' => ['varchar(255)','']];
+                $this->setDefaultCharsetAndCollation($tableName, $columns, $connection);
+            }
         }
     }

@@ -758,6 +791,14 @@ private function setupCacheTable(
                 'Caches'
             );
             $connection->createTable($table);
+        } else {
+            // change the charset to utf8mb4
+            $getTableSchema = $connection->getCreateTable($setup->getTable('cache')) ?? '';
+            if (preg_match('/\b('. self::OLDCHARSET .')\b/', $getTableSchema)) {
+                $tableName = $setup->getTable('cache');
+                $columns = ['id' => ['varchar(200)','']];
+                $this->setDefaultCharsetAndCollation($tableName, $columns, $connection);
+            }
         }
     }

@@ -795,6 +836,14 @@ private function setupCacheTagTable(
                 'Tag Caches'
             );
             $connection->createTable($table);
+        } else {
+            // Set default collation to utf8mb4 for MySQL
+            $getTableSchema = $connection->getCreateTable($setup->getTable('cache_tag')) ?? '';
+            if (preg_match('/\b('. self::OLDCHARSET .')\b/', $getTableSchema)) {
+                $tableName = $setup->getTable('cache_tag');
+                $columns = ['tag' => ['varchar(100)',''],'cache_id' => ['varchar(200)','']];
+                $this->setDefaultCharsetAndCollation($tableName, $columns, $connection);
+            }
         }
     }

@@ -853,6 +902,12 @@ private function setupFlagTable(
             $connection->createTable($table);
         } else {
             $this->updateColumnType($connection, $tableName, 'flag_data', 'mediumtext');
+            // change the charset to utf8mb4
+            $getTableSchema = $connection->getCreateTable($tableName) ?? '';
+            if (preg_match('/\b('. self::OLDCHARSET .')\b/', $getTableSchema)) {
+                $columns = ['flag_code' => ['varchar(255)','NOT NULL'],'flag_data' => ['mediumtext','']];
+                $this->setDefaultCharsetAndCollation($tableName, $columns, $connection);
+            }
         }
     }

@@ -1827,4 +1882,25 @@ private function setIndexerModeSchedule(): void
             $this->log->log(__("We couldn't change indexer(s)' mode because of an error: ".$e->getMessage()));
         }
     }
+
+    /**
+     * Set default collation & charset (e.g. utf8mb4_general_ci and utf8mb4) for core setup tables
+     *
+     * @param string $tableName
+     * @param array $columns
+     * @param AdapterInterface $connection
+     * @return void
+     */
+    private function setDefaultCharsetAndCollation(string $tableName, array $columns, $connection) : void
+    {
+        $charset = $this->columnConfig->getDefaultCharset();
+        $collate = $this->columnConfig->getDefaultCollation();
+        $encoding = " CHARACTER SET ".$charset." COLLATE ".$collate;
+        $qry = sprintf('ALTER TABLE %s ', $tableName);
+        foreach ($columns as $key => $prop) {
+            $qry .= "MODIFY COLUMN `$key` $prop[0] $encoding $prop[1], ";
+        }
+        $qry .= sprintf('DEFAULT CHARSET=%s, DEFAULT COLLATE=%s', $charset, $collate);
+        $connection->query($qry);
+    }
 }

