ubuntu升级后MySQL数据库出现问题

问题描述 投票:0回答:1

我们有一台旧服务器,直到昨天还在运行 2016 版本的 Ubuntu。服务器速度超级快(不到 1 秒就提供了一个复杂的页面)。由于我们需要 PHP8.2,我们决定升级到 Ubuntu22。

升级后系统很慢,同样的页面需要30秒左右才能生成!!!!

经过调查,我认为问题是由于MySQL造成的。升级之前我们的数据库如下:

-- MySQL dump 10.13  Distrib 5.7.33, for Linux (x86_64)
--
-- Host: localhost    Database: website
-- ------------------------------------------------------
-- Server version   5.7.33-0ubuntu0.16.04.1

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `articleBookmarks`
--

DROP TABLE IF EXISTS `articleBookmarks`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `articleBookmarks` (
  `bookmarkId` int(11) NOT NULL AUTO_INCREMENT,
  `userId` int(11) DEFAULT NULL,
  `articleId` char(16) DEFAULT NULL,
  `category` int(11) DEFAULT NULL,
  `addDate` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`bookmarkId`)
) ENGINE=InnoDB AUTO_INCREMENT=99 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

升级后我有

-- MySQL dump 10.13  Distrib 8.0.36, for Linux (x86_64)
--
-- Host: localhost    Database: website
-- ------------------------------------------------------
-- Server version   8.0.36-0ubuntu0.22.04.1

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `articleBookmarks`
--

DROP TABLE IF EXISTS `articleBookmarks`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `articleBookmarks` (
  `bookmarkId` int NOT NULL AUTO_INCREMENT,
  `userId` int DEFAULT NULL,
  `articleId` char(16) DEFAULT NULL,
  `category` int DEFAULT NULL,
  `addDate` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`bookmarkId`)
) ENGINE=InnoDB AUTO_INCREMENT=135 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

看来ubuntu决定在不询问的情况下将字符集从utf8更改/转换为utf8mb4!

因此,数据库错误地显示了所有表情符号和空间符号。例如,微笑表情符号现在显示为“ðŸ~‚”。

此外,我无法在数据库中插入更多记录。我收到以下错误:

[2024 年 3 月 26 日星期二 15:27:25.623713 2024] [php:error] [pid 4341] [client 40.xx.xxx.xxx:52355] PHP 致命错误:未捕获 mysqli_sql_exception:参数中不可能从排序规则 utf8mb4_0900_ai_ci 转换为 latin1_swedish_ci /var/www/html/MyPHPfunction.php:8630 堆栈跟踪: #0 /var/www/html/MyPHPfunction.php(8630): mysqli_stmt->execute() #1 /var/www/html/funct2.php(398): show_search_results() #2 {主要} 扔进 /var/www/html/funct2.php 第 8630 行

我找不到任何有 latin1_swedish_ci 的桌子

有人知道如何解决这个问题吗?整个服务器目前在某种程度上毫无用处:(

mysql ubuntu
1个回答
0
投票

在进行此类大规模更改之前确认您拥有可用的备份,并在针对任何生产数据运行之前在副本上测试更改,这一点非常重要。

您很可能最终在 latin1 列中存储了 UTF-8 字符。在数据库服务器升级之前,连接字符集和列字符集都是 latin1,因此在读取和/或写入数据库时不会发生隐式字符转换。现在默认字符集是utf8mb4,连接是utf8mb4,但列是latin1。这会导致隐式字符转换,从而破坏您的数据。

要确认上述假设,请针对您知道包含显示不正确的数据的表/列运行以下 SELECT。通过 utf8mb4 连接执行此操作非常重要。

SELECT `name`, CONVERT(CONVERT(`name` USING binary) USING utf8mb4)
FROM `your_db_name`.`test1`;

我希望第一列包含损坏的版本,第二列是正确的。

如果上述情况证实了怀疑的情况,则可以使用 information_schema 来编写所有 ALTER TABLE 语句。像这样的东西:

SELECT CONCAT(
    'ALTER TABLE `', TABLE_SCHEMA, '`.`', TABLE_NAME, '`\n',
    GROUP_CONCAT(
        '\tMODIFY COLUMN `', COLUMN_NAME, '` ',
        IF(DATA_TYPE IN ('varchar', 'char'), CONCAT('varbinary(', CHARACTER_MAXIMUM_LENGTH, ')'), 'blob'),
        IF(IS_NULLABLE = 'NO', ' NOT NULL', ''),
        IF(COLUMN_DEFAULT IS NOT NULL, CONCAT('DEFAULT \'', COLUMN_DEFAULT, '\''), '')
        SEPARATOR ',\n'
    ),
    ';\n'
    'ALTER TABLE `', TABLE_SCHEMA, '`.`', TABLE_NAME, '`\n',
    GROUP_CONCAT(
        '\tMODIFY COLUMN `', COLUMN_NAME, '` ',
        COLUMN_TYPE, ' CHARACTER SET utf8mb4',
        IF(IS_NULLABLE = 'NO', ' NOT NULL', ''),
        IF(COLUMN_DEFAULT IS NOT NULL, CONCAT('DEFAULT \'', COLUMN_DEFAULT, '\''), '')
        SEPARATOR ',\n'
    ),
    ',\n\tDEFAULT CHARACTER SET utf8mb4;\n'
) AS `alter_stmt`
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'your_db_name'
AND DATA_TYPE IN ('varchar', 'char', 'text')
AND CHARACTER_SET_NAME = 'latin1'
GROUP BY TABLE_NAME;

给出一个像这样的简单表格:

CREATE TABLE `your_db_name`.`test1` (
  `id` int NOT NULL,
  `name` varchar(255) NOT NULL,
  `description` text NOT NULL,
  `col1` char(2) DEFAULT NULL,
  `status` tinyint NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

上面的查询将输出类似:

ALTER TABLE `your_db_name`.`test1`
    MODIFY COLUMN `name` varbinary(255) NOT NULL,
    MODIFY COLUMN `description` blob NOT NULL,
    MODIFY COLUMN `col1` varbinary(2);
ALTER TABLE `your_db_name`.`test1`
    MODIFY COLUMN `name` varchar(255) CHARACTER SET utf8mb4 NOT NULL,
    MODIFY COLUMN `description` text CHARACTER SET utf8mb4 NOT NULL,
    MODIFY COLUMN `col1` char(2) CHARACTER SET utf8mb4,
    DEFAULT CHARACTER SET utf8mb4;

如果需要,您可以修改信息架构查询以添加适当的排序规则和列注释。

© www.soinside.com 2019 - 2024. All rights reserved.