MySQL8 中文参考(一百一十五)

原文:docs.oracle.com/javase/tutorial/reallybigindex.html

A.10 MySQL 8.0 FAQ: NDB Cluster

原文:dev.mysql.com/doc/refman/8.0/en/faqs-mysql-cluster.html

在接下来的部分中,我们回答了关于 MySQL NDB Cluster 和NDB存储引擎经常被问到的问题。

A.10.1. MySQL 软件的哪些版本支持 NDB Cluster?我需要从源代码编译吗?

A.10.2. “NDB”和“NDBCLUSTER”是什么意思?

A.10.3. 使用 NDB Cluster 与使用 MySQL 复制有什么区别?

A.10.4. 运行 NDB Cluster 需要特殊的网络设置吗?集群中的计算机如何通信?

A.10.5. 运行 NDB Cluster 需要多少台计算机,以及为什么?

A.10.6. NDB Cluster 中的不同计算机有什么作用?

A.10.7. 当我在 NDB Cluster 管理客户端中运行 SHOW 命令时,我看到一行输出看起来像这样:

A.10.8. 我可以在哪些操作系统上使用 NDB Cluster?

A.10.9. 运行 NDB Cluster 的硬件要求是什么?

A.10.10. 我需要多少 RAM 才能使用 NDB Cluster?是否可以使用磁盘内存?

A.10.11. NDB Cluster 可以使用哪些文件系统?网络文件系统或网络共享呢?

A.10.12. 我可以在虚拟机中运行 NDB Cluster 节点吗(比如 VMWare、VirtualBox、Parallels 或 Xen 创建的)?

A.10.13. 我正在填充 NDB Cluster 数据库。加载过程提前终止,我收到了这样的错误消息:

A.10.14. NDB Cluster 使用 TCP/IP。这是否意味着我可以在 Internet 上运行它,远程位置有一个或多个节点?

A.10.15. 我是否需要学习新的编程或查询语言来使用 NDB Cluster?

A.10.16. NDB Cluster 支持哪些编程语言和 API?

A.10.17. NDB Cluster 包含哪些管理工具?

A.10.18. 在使用 NDB Cluster 时,如何查找错误或警告消息的含义?

A.10.19. NDB Cluster 是否支持事务安全?支持哪些隔离级别?

A.10.20. NDB Cluster 支持哪些存储引擎?

A.10.21. 在发生灾难性故障时——例如,整个城市停电并且我的不间断电源失效——我会丢失所有数据吗?

A.10.22. 是否可以在 NDB Cluster 中使用全文索引?

A.10.23. 我可以在单台计算机上运行多个节点吗?

A.10.24. 我可以在不重启的情况下向 NDB Cluster 添加数据节点吗?

A.10.25. 在使用 NDB Cluster 时,有哪些限制我应该注意?

A.10.26. NDB Cluster 支持外键吗?

A.10.27. 如何将现有的 MySQL 数据库导入 NDB Cluster?

A.10.28. NDB Cluster 节点如何相互通信?

A.10.29. 什么是仲裁者?

A.10.30. NDB Cluster 支持哪些数据类型?

A.10.31. 如何启动和停止 NDB Cluster?

A.10.32. 当集群关闭时,NDB Cluster 数据会发生什么?

A.10.33. 为 NDB Cluster 拥有多个管理节点是个好主意吗?

A.10.34. 我可以在一个 NDB Cluster 中混合不同类型的硬件和操作系统吗?

A.10.35. 我可以在单个主机上运行两个数��节点吗?两个 SQL 节点?

A.10.36. 我可以在 NDB Cluster 中使用主机名吗?

A.10.37. NDB Cluster 支持 IPv6 吗?

A.10.38. 在 NDB Cluster 中如何处理具有多个 MySQL 服务器的 MySQL 用户?

A.10.39. 在一个 SQL 节点失败的情况下,如何继续发送查询?

A.10.40. 如何备份和恢复 NDB Cluster?

A.10.41. 什么是“天使进程”?

A.10.1.MySQL 软件的哪些版本支持 NDB Cluster?我是否必须从源代码编译?

| | NDB Cluster 不支持标准 MySQL Server 版本。相反,MySQL NDB Cluster 作为一个独立产品提供。可用的 NDB Cluster 发布系列包括以下内容:

  • **NDB Cluster 7.3 / NDB Cluster 7.4. ** 这两个系列不再维护或支持新部署。NDB Cluster 7.3 或 7.4 的用户应尽快升级到 NDB 7.5 或更新版本。我们建议新部署使用最新的 NDB Cluster 8.0 版本。

  • **NDB Cluster 7.5. ** 这个系列是 NDB Cluster 的以前的通用可用性(GA)版本,仍然可用于生产使用,尽管我们建议新部署使用最新的 NDB Cluster 8.0 版本。最新的 NDB Cluster 7.5 版本可以从dev.mysql.com/downloads/cluster/获取。

  • **NDB Cluster 7.6. ** 这个系列是 NDB Cluster 的以前的通用可用性(GA)版本,仍然可用于生产使用,尽管我们建议新部署使用最新的 NDB Cluster 8.0 版本。最新的 NDB Cluster 7.6 版本可以从dev.mysql.com/downloads/cluster/获取。

  • **NDB Cluster 8.0. ** 这个系列是 NDB Cluster 的最新通用可用性(GA)版本,基于NDB存储引擎的 8.0 版本和 MySQL Server 8.0. NDB Cluster 8.0 可用于生产使用;新的用于生产的部署应该使用此系列中最新的 GA 版本,目前是 NDB Cluster 8.0.35. 您可以从dev.mysql.com/downloads/cluster/获取最新的 NDB Cluster 8.0 版本。有关此系列中的新功能和其他重要更改的信息,请参见第 25.2.4 节,“MySQL NDB Cluster 8.0 中的新功能”。

您可以从源代码获取并编译 NDB Cluster(参见第 25.3.1.4 节,“在 Linux 上从源代码构建 NDB Cluster”,以及第 25.3.2.2 节,“在 Windows 上从源代码编译和安装 NDB Cluster”),但除非是最专业的情况,我们建议使用 Oracle 提供的适合您操作平台和情况的以下安装程序:

  • Linux 二进制版本(tar.gz 文件)

  • Linux RPM 软件包

  • Linux .deb 文件

  • Windows 二进制“无需安装”版本

  • Windows MSI 安装程序

安装包也可能来自您平台的软件包管理系统。您可以使用以下语句之一来确定您的 MySQL 服务器是否支持 NDBSHOW VARIABLES LIKE 'have_%'SHOW ENGINESSHOW PLUGINS。 |

A.10.2.“NDB” 和 “NDBCLUSTER” 是什么意思?
NDB 代表 “Network Database”。NDBNDBCLUSTER 都是启用 MySQL 集群支持的存储引擎的名称。NDB 是首选,但两个名称都是正确的。
A.10.3.使用 NDB Cluster 与使用 MySQL 复制有什么区别?
在传统的 MySQL 复制中,源 MySQL 服务器更新一个或多个副本。事务按顺序提交,一个慢事务可能导致副本落后于源服务器。这意味着如果源服务器失败,副本可能没有记录最后几个事务。如果正在使用事务安全引擎如 InnoDB,事务要么在副本上完成,要么根本不被应用,但复制不能保证源服务器和副本上的所有数据始终保持一致。在 NDB Cluster 中,所有数据节点保持同步,任何一个数据节点提交的事务对所有数据节点都是提交的。在数据节点故障的情况下,所有剩余的数据节点保持一致。简而言之,标准 MySQL 复制是异步的,而 NDB Cluster 是同步的。NDB Cluster 也支持异步复制。NDB Cluster 复制(有时也称为“地理复制”)包括在两个 NDB Cluster 之间复制,以及从 NDB Cluster 到非集群 MySQL 服务器的复制。参见 第 25.7 节 “NDB Cluster 复制”。
A.10.4.运行 NDB Cluster 需要特殊的网络设置吗?集群中的计算机如何通信?
NDB Cluster 旨在在高带宽环境中使用,计算机通过 TCP/IP 连接。其性能直接取决于集群计算机之间的连接速度。NDB Cluster 的最低连接要求包括典型的 100 兆位以太网网络或等效网络。我们建议您在可用时使用千兆以太网。
A.10.5.运行 NDB Cluster 需要多少台计算机,以及为什么?
至少需要三台计算机才能运行一个可行的集群。然而,在 NDB Cluster 中,最低推荐计算机数量为四台:一台用于运行管理和 SQL 节点,另外两台用作数据节点。这两个数据节点的目的是提供冗余性;管理节点必须在单独的机器上运行,以确保在其中一个数据节点发生故障时继续提供仲裁服务。为了提供增加的吞吐量和高可用性,您应该使用多个 SQL 节点(连接到集群的 MySQL 服务器)。也可以(虽然不是绝对必要)运行多个管理服务器。
A.10.6.NDB Cluster 中的不同计算机扮演什么角色?

| | NDB Cluster 既有物理组织,也有逻辑组织,计算机是物理元素。集群的逻辑或功能元素称为节点,容纳集群节点的计算机有时被称为集群主机。有三种类型的节点,每种对应于集群中的特定角色。这些是:

  • 管理节点。 此节点为整个集群提供管理服务,包括启动、关闭、备份和其他节点的配置数据。管理节点服务器实现为应用程序ndb_mgmd;用于控制 NDB Cluster 的管理客户端是ndb_mgm。有关这些程序的信息,请参见第 25.5.4 节,“ndb_mgmd — NDB Cluster 管理服务器守护程序”,以及第 25.5.5 节,“ndb_mgm — NDB Cluster 管理客户端”。

  • 数据节点。 这种类型的节点存储和复制数据。数据节点功能由NDB数据节点进程ndbd的实例处理。有关更多信息,请参见第 25.5.1 节,“ndbd — NDB Cluster 数据节点守护程序”。

  • SQL 节点。 这只是一个构建有对NDBCLUSTER存储引擎支持的 MySQL 服务器实例(mysqld),并使用--ndb-cluster选项启动以启用引擎和--ndb-connectstring选项以使其连接到 NDB Cluster 管理服务器。有关这些选项的更多信息,请参见 Section 25.4.3.9.1, “MySQL Server Options for NDB Cluster”。

    注意

    API 节点是任何直接使用集群数据节点进行数据存储和检索的应用程序。因此,SQL 节点可以被视为一种使用 MySQL 服务器提供 SQL 接口给集群的 API 节点。您可以使用 NDB API 编写这种应用程序(不依赖于 MySQL 服务器),NDB API 提供了直接的、面向对象的事务和扫描接口给 NDB Cluster 数据;更多信息请参见 NDB Cluster API 概述:NDB API。

|

| A.10.7. | 当我在 NDB Cluster 管理客户端中运行SHOW命令时,我看到一行输出看起来像这样:

id=2    @10.100.10.32  (Version: 8.0.35-ndb-8.0.35 Nodegroup: 0, *)

*代表什么?这个节点与其他节点有什么不同?

最简单的答案是,“这不是你可以控制的东西,无论如何也不需要担心,除非你是一名编写或分析 NDB Cluster 源代码的软件工程师”。如果你觉得这个答案不够满意,这里有一个更长、更技术性的版本:NDB Cluster 中的许多机制需要数据节点之间的分布式协调。这些分布式算法和协议包括全局检查点、DDL(模式)更改和节点重启处理。为了使这种协调更简单,数据节点“选举”其中一个成员作为领导者。没有用户可影响此选择的机制,这完全是自动的;自动性是 NDB Cluster 内部架构的关键部分。当一个节点作为任何这些机制的“领导者”时,通常是活动的协调点,其他节点作为“跟随者”,按照领导者的指示执行他们的活动部分。如果充当领导者的节点失败,剩余节点将选举新的领导者。由旧领导者协调的正在进行的任务可能会失败,也可能由新领导者继续,这取决于实际涉及的机制。一些不同的机制和协议可能有不同的领导节点,但通常为它们选择相同的领导者。在管理客户端的SHOW输出中指示为领导者的节点在内部被称为DICT管理器,负责协调 DDL 和元数据活动。NDB Cluster 设计成领导者的选择对集群外部没有明显影响。例如,当前领导者的 CPU 或资源使用率并不比其他数据节点高出很多,领导者的失败对集群的影响不应与任何其他数据节点的失败有明显不同。
A.10.8.我可以在哪些操作系统上使用 NDB Cluster?
NDB Cluster 支持大多数类 Unix 操作系统。NDB Cluster 也在 Microsoft Windows 操作系统上的生产环境中得到支持。有关 NDB Cluster 在各种操作系统版本、操作系统发行版和硬件平台上提供的支持级别的更详细信息,请参考www.mysql.com/support/supportedplatforms/cluster.html
A.10.9.运行 NDB Cluster 的硬件要求是什么?
NDB Cluster 应该在任何可用 NDB 启用二进制文件的平台上运行。对于数据节点和 API 节点,更快的 CPU 和更多的内存可能会提高性能,64 位 CPU 可能比 32 位处理器更有效。在用于数据节点的机器上必须有足够的内存来存储每个节点的数据库份额(有关更多信息,请参阅 需要多少 RAM?)。对于仅用于运行 NDB Cluster 管理服务器的计算机,要求很低;通常普通的台式 PC(或等效物)就足够完成这项任务。节点可以通过标准 TCP/IP 网络和硬件进行通信。它们还可以使用高速 SCI 协议;但是,使用 SCI 需要特殊的网络硬件和软件(请参阅第 25.4.4 节,“使用 NDB Cluster 的高速互连”)。
A.10.10.我需要多少 RAM 才能使用 NDB Cluster?是否可以完全使用磁盘内存?

| | NDB Cluster 最初仅作为内存实现,但当前所有版本也提供了将 NDB Cluster 存储在磁盘上的功能。查看第 25.6.11 节,“NDB Cluster 磁盘数据表”,获取更多信息。对于内存中的 NDB 表,您可以使用以下公式来粗略估算集群中每个数据节点所需的 RAM:

(SizeofDatabase × NumberOfReplicas × 1.1 ) / NumberOfDataNodes

要更精确地计算内存需求,需要确定集群数据库中每个表的每行所需的存储空间(有关详细信息,请参阅第 13.7 节,“数据类型存储需求”),并将其乘以行数。您还必须记住按照以下方式考虑任何列索引:

  • NDBCLUSTER 表创建的每个主键或哈希索引需要每条记录 21-25 字节。这些索引使用 IndexMemory

  • 每个有序索引需要每条记录 10 字节的存储空间,使用 DataMemory

  • 创建主键或唯一索引也会创建一个有序索引,除非此索引是使用 USING HASH 创建的。换句话说:

    • 集群表上的主键或唯一索引通常每条记录占用 31 到 35 字节。

    • 但是,如果主键或唯一索引是使用 USING HASH 创建的,则每条记录仅需要 21 到 25 字节。

使用USING HASH为所有主键和唯一索引创建 NDB Cluster 表通常会使表更新速度更快——在某些情况下比未在创建主键和唯一键时使用USING HASH的表快 20 到 30%。这是因为需要的内存更少(因为没有创建有序索引),并且需要利用的 CPU 更少(因为需要读取和可能更新的索引更少)。然而,这也意味着否则可以使用范围扫描的查询必须通过其他方式满足,这可能导致选择速度变慢。在计算集群内存需求时,您可能会发现最近 MySQL 8.0 版本中提供的ndb_size.pl实用程序很有用。这个 Perl 脚本连接到当前(非集群)MySQL 数据库,并创建一个报告,说明如果该数据库使用NDBCLUSTER存储引擎,该数据库将需要多少空间。有关更多信息,请参见 Section 25.5.28, “ndb_size.pl — NDBCLUSTER Size Requirement Estimator”。特别重要的是要记住每个 NDB Cluster 表必须有一个主键。如果未定义主键,则NDB存储引擎会自动创建一个主键;此主键是在不使用USING HASH的情况下创建的。您可以使用ndb_mgm客户端中的REPORT MEMORYUSAGE命令随时确定 NDB Cluster 数据和索引的存储使用情况;有关更多信息,请参见 Section 25.6.1, “Commands in the NDB Cluster Management Client”。此外,当可用DataMemory的 80%或(在 NDB 7.6 之前)IndexMemory被使用时,警告将写入集群日志,并且当使用率达到 90%,99%和 100%时再次写入。 |

A.10.11.我可以在 NDB Cluster 中使用哪些文件系统?网络文件系统或网络共享呢?
一般来说,任何与主机操作系统原生兼容的文件系统都可以很好地与 NDB Cluster 配合使用。如果您发现某个文件系统与 NDB Cluster 特别适配(或者不太适配),我们邀请您在NDB Cluster 论坛中讨论您的发现。对于 Windows,我们建议您像标准 MySQL 一样使用NTFS文件系统来运行 NDB Cluster。我们不测试 NDB Cluster 与FATVFAT文件系统的兼容性。因此,我们不建议在 MySQL 或 NDB Cluster 中使用它们。NDB Cluster 被实现为一种共享无解决方案;其背后的理念是,单个硬件部件的故障不应导致多个集群节点的故障,甚至可能导致整个集群的故障。因此,不支持使用网络共享或网络文件系统来运行 NDB Cluster。这也适用于 SAN 等共享存储设备。
A.10.12.我可以在虚拟机中(如 VMWare、VirtualBox、Parallels 或 Xen 创建的虚拟机)运行 NDB Cluster 节点吗?
NDB Cluster 支持在虚拟机中使用。我们目前支持并测试使用Oracle VM。一些 NDB Cluster 用户已成功部署了 NDB Cluster,使用了其他虚拟化产品;在这种情况下,Oracle 可以提供 NDB Cluster 支持,但特定于虚拟环境的问题必须向该产品的供应商咨询。
A.10.13.我正在尝试填充一个 NDB Cluster 数据库。加载过程会过早终止,并且我会收到这样的错误消息:ERROR 1114: 表'my_cluster_table'已满。为什么会发生这种情况?
很可能的原因是您的设置为所有表数据和所有索引提供的 RAM 不足,包括NDB存储引擎所需的主键,在表定义中没有包含主键定义时会自动创建。值得注意的是,所有数据节点应该具有相同数量的 RAM,因为集群中的任何数据节点都不能使用比任何单个数据节点可用的最少内存更多的内存。例如,如果有四台计算机托管集群数据节点,其中三台有 3GB 的 RAM 可用于存储集群数据,而剩下的数据节点只有 1GB 的 RAM,则每个数据节点最多可以将 1GB 用于 NDB Cluster 数据和索引。在某些情况下,即使**ndb_mgm -e “ALL REPORT MEMORYUSAGE”**显示有显着空闲的DataMemory,在 MySQL 客户端应用程序中也可能出现“表已满”错误。您可以通过为CREATE TABLE使用MAX_ROWS选项,强制NDB为 NDB Cluster 表创建额外的分区,从而为哈希索引提供更多可用内存。通常,将MAX_ROWS设置为您预计在表中存储的行数的两倍应该足够。出于类似的原因,有时您可能在负载较重的节点上遇到数据节点重新启动的问题。MinFreePct参数可以通过保留一部分(默认为 5%)DataMemory和(在 NDB 7.6 之前)IndexMemory来帮助解决此问题,用于重新启动。此保留的内存不可用于存储NDB表或数据。
A.10.14.NDB Cluster 使用 TCP/IP。这是否意味着我可以在 Internet 上运行它,其中一个或多个节点位于远程位置?
在这种情况下,集群能够可靠地运行的可能性非常小,因为 NDB 集群的设计和实现是基于这样的假设:它将在保证专用高速连接的条件下运行,例如在使用 100 Mbps 或千兆以太网的局域网设置中,最好是后者。我们既不测试也不保证在比这慢的任何情况下的性能。此外,需要牢记的是,NDB 集群中节点之间的通信不安全;它们既不加密也不受到任何其他保护机制的保护。集群的最安全配置是在防火墙后的私人网络中,外部无法直接访问任何集群数据或管理节点。(对于 SQL 节点,您应该像对待 MySQL 服务器的任何其他实例一样采取相同的预防措施。)有关更多信息,请参阅第 25.6.20 节,“NDB 集群安全问题”。
A.10.15.我需要学习新的编程或查询语言才能使用 NDB 集群吗?

| | 不需要。虽然一些专门的命令用于管理和配置集群本身,但以下操作仅需要标准(My)SQL 语句:

  • 创建、修改和删除表格

  • 插入、更新和删除表格数据

  • 创建、更改和删除主键和唯一索引

设置 NDB 集群需要一些专门的配置参数和文件,请参阅第 25.4.3 节,“NDB 集群配置文件”,了解相关信息。在 NDB 集群管理客户端(ndb_mgm)中使用一些简单的命令,如启动和停止集群节点。请参阅第 25.6.1 节,“NDB 集群管理客户端中的命令”。 |

A.10.16.NDB 集群支持哪些编程语言和 API?
NDB Cluster 支持与标准 MySQL Server 相同的编程 API 和语言,包括 ODBC、.Net、MySQL C API 以及用于流行脚本语言(如 PHP、Perl 和 Python)的许多驱动程序。使用这些 API 编写的 NDB Cluster 应用程序的行为类似于其他 MySQL 应用程序;它们将 SQL 语句传输到 MySQL Server(在 NDB Cluster 的情况下,是一个 SQL 节点),并接收包含数据行的响应。有关这些 API 的更多信息,请参阅 Chapter 31, Connectors and APIs。NDB Cluster 还支持使用 NDB API 进行应用程序编程,该 API 提供了一个低级的 C++接口,用于访问 NDB Cluster 数据而无需经过 MySQL Server。请参阅 NDB API。此外,许多NDBCLUSTER管理功能通过 C 语言 MGM API 公开;有关更多信息,请参阅 MGM API。NDB Cluster 还支持使用 ClusterJ 进行 Java 应用程序编程,该工具支持使用会话和事务的数据域对象模型。有关更多信息,请参阅 Java and NDB Cluster。NDB Cluster 8.0 还包括支持使用 NDB Cluster 作为数据存储的Node.js的 NoSQL 应用程序的适配器。有关更多信息,请参阅 MySQL NoSQL Connector for JavaScript。
A.10.17.NDB Cluster 包括哪些管理工具?
NDB Cluster 包括一个用于执行基本管理功能的命令行客户端。请参阅 Section 25.5.5, “ndb_mgm — The NDB Cluster Management Client”,以及 Section 25.6.1, “Commands in the NDB Cluster Management Client”。NDB Cluster 还受到 MySQL Cluster Manager 的支持,这是一个提供高级命令行界面的独立产品,可以自动化许多 NDB Cluster 管理任务,如滚动重启和配置更改。有关 MySQL Cluster Manager 的更多信息,请参阅 MySQL Cluster Manager 8.0.36 User Manual。
A.10.18.当使用 NDB Cluster 时,如何找出错误或警告消息的含义?

| | 有两种方法可以实现这��点:

  • mysql客户端内部,在收到错误或警告条件的通知后立即使用SHOW ERRORSSHOW WARNINGS

  • 从系统 shell 提示符中,使用 perror --ndb error_code

|

A.10.19.NDB Cluster 是否支持事务安全?支持哪些隔离级别?
是的。对于使用 NDB 存储引擎创建的表,支持事务。目前,NDB Cluster 仅支持 READ COMMITTED 事务隔离级别。
A.10.20.NDB Cluster 支持哪些存储引擎?
NDB Cluster 需要 NDB 存储引擎。也就是说,为了使表在 NDB Cluster 中的节点之间共享,必须使用 ENGINE=NDB(或等效选项 ENGINE=NDBCLUSTER)创建表。在与 NDB Cluster 一起使用的 MySQL 服务器上可以使用其他存储引擎(如 InnoDBMyISAM)创建表,但由于这些表不使用 NDB,它们不参与集群化;每个这样的表严格限定在创建它的个别 MySQL 服务器实例中。NDB Cluster 在架构、要求和实现方面与 InnoDB 集群有很大不同;尽管它们的名称相似,但两者不兼容。有关 InnoDB 集群的更多信息,请参阅 MySQL AdminAPI。另请参阅 第 25.2.6 节,“使用 InnoDB 的 MySQL 服务器与 NDB Cluster 比较”,了解 NDBInnoDB 存储引擎之间的区别。
A.10.21.在发生灾难性故障时——例如,整个城市停电 并且 我的 UPS 失效——我会丢失所有数据吗?
所有提交的事务都被记录。因此,尽管在灾难发生时可能会丢失一些数据,但这应该是相当有限的。通过最小化每个事务的操作数量,可以进一步减少数据丢失。(无论如何,一次执行大量操作的事务都不是一个好主意。)
A.10.22.是否可以在 NDB Cluster 中使用 FULLTEXT 索引?
FULLTEXT 索引目前仅由 InnoDBMyISAM 存储引擎支持。有关更多信息,请参阅 第 14.9 节,“全文搜索函数”。
A.10.23.我可以在一台计算机上运行多个节点吗?
可以,但并非总是明智之举。运行集群的主要原因之一是提供冗余。为了获得这种冗余的全部好处,每个节点应该位于单独的机器上。如果将多个节点放在一台机器上,而该机器发生故障,那么所有这些节点都会丢失。因此,如果在单台机器上运行多个数据节点,非常重要的是要设置它们,以使该机器的故障不会导致给定节点组中所有数据节点的丢失。考虑到 NDB Cluster 可以在装载了低成本(甚至零成本)操作系统的商品硬件上运行,为了保护关键数据,额外购买一两台机器是非常值得的。还值得注意的是,运行管理节点的集群主机的要求很低。这项任务可以通过一台 300 MHz 的 Pentium 或等效 CPU 和足够的 RAM 用于操作系统,再加上一些用于 ndb_mgmdndb_mgm 进程的额外开销来完成。在具有多个 CPU、核心或两者的单个主机上运行多个集群数据节点是可以接受的。NDB Cluster 发行版还提供了数据节点二进制文件的多线程版本,旨在用于这些系统。有关更多信息,请参阅 第 25.5.3 节,“ndbmtd — NDB Cluster 数据节点守护进程(多线程)”。在某些情况下,还可以在同一台机器上同时运行数据节点和 SQL 节点;这种安排的性能如何取决于诸多因素,如核心和 CPU 的数量,以及数据节点和 SQL 节点进程可用的磁盘和内存量,您必须在规划这种配置时考虑这些因素。
A.10.24.我可以在不重启 NDB Cluster 的情况下���加数据节点吗?
可以在运行中的 NDB Cluster 中添加新的数据节点而无需将集群下线。有关更多信息,请参阅 第 25.6.7 节,“在线添加 NDB Cluster 数据节点”。对于其他类型的 NDB Cluster 节点,只需要进行滚动重启(参见 第 25.6.5 节,“执行 NDB Cluster 的滚动重启”)即可。
A.10.25.在使用 NDB Cluster 时,我应该注意哪些限制吗?

| | 在 MySQL NDB Cluster 中,对NDB 表的限制包括以下内容:

  • 不支持临时表;使用ENGINE=NDBENGINE=NDBCLUSTERCREATE TEMPORARY TABLE语句会导致错误。

  • 仅支持NDBCLUSTER表的KEYLINEAR KEY两种用户定义的分区类型。尝试使用其他分区类型创建NDB表会导致错误。

  • 不支持FULLTEXT索引。

  • 不支持索引前缀。只能对完整列建立索引。

  • 不支持空间索引(尽管可以使用空间列)。请参见第 13.4 节,“空间数据类型”。

  • 支持部分事务和部分回滚的程度与其他事务存储引擎(如InnoDB)相当,可以回滚单个语句。

  • 每个表允许的最大属性数为 512。属性名称不能超过 31 个字符。对于每个表,表名和数据库名的最大组合长度为 122 个字符。

  • 在 NDB 8.0 之前,表行的最大大小为 14 千字节,不包括BLOB值。在 NDB 8.0 中,这个最大值增加到 30000 字节。有关更多信息,请参见第 25.2.7.5 节,“NDB 集群中与数据库对象相关的限制”。

    每个NDB表的行数没有固定限制。表大小的限制取决于许多因素,特别是每个数据节点可用的 RAM 量。

有关 NDB 集群中限制的完整列表,请参见第 25.2.7 节,“NDB 集群的已知限制”。另请参见第 25.2.7.11 节,“NDB 集群 8.0 中已解决的先前 NDB 集群问题”。 |

A.10.26.NDB 集群支持外键吗?
NDB 集群提供了与InnoDB存储引擎中相似的外键约束支持;有关更详细信息,请参见第 1.6.3.2 节,“FOREIGN KEY 约束”,以及第 15.1.20.5 节,“FOREIGN KEY 约束”。需要外键支持的应用程序应使用 NDB 集群 7.3、7.4、7.5 或更高版本。
A.10.27.如何将现有的 MySQL 数据库导入 NDB 集群中?
您可以像使用任何其他版本的 MySQL 一样将数据库导入 NDB 集群。除了本 FAQ 中其他地方提到的限制之外,唯一的其他特殊要求是要包含在集群中的任何表必须使用NDB存储引擎。这意味着表必须使用ENGINE=NDBENGINE=NDBCLUSTER创建。还可以使用一个或多个ALTER TABLE语句将使用其他存储引擎的现有表转换为NDBCLUSTER。但是,在进行转换之前,表的定义必须与NDBCLUSTER存储引擎兼容。在 MySQL 8.0 中,还需要额外的解决方法;有关详细信息,请参见第 25.2.7 节,“NDB 集群的已知限制”。
A.10.28.NDB 集群节点如何相互通信?
集群节点可以通过三种不同的传输机制进行通信:TCP/IP、SHM(共享内存)和 SCI(可扩展一致性接口)。在可用的情况下,同一集群主机上的节点之间默认使用 SHM;然而,这被视为实验性质。SCI 是一种高速(每秒 1 千兆位及更高)、高可用性协议,用于构建可扩展的多处理器系统;它需要特殊的硬件和驱动程序。有关将 SCI 用作 NDB 集群的传输机制的更多信息,请参见第 25.4.4 节,“使用高速互连与 NDB 集群”。
A.10.29.仲裁者是什么?
如果集群中的一个或多个数据节点发生故障,可能导致并非所有集群数据节点都能“看到”彼此。事实上,在网络分区中,两组数据节点可能会相互隔离,也就是所谓的“脑裂”场景。这种情况是不可取的,因为每组数据节点都试图表现得像整个集群一样。需要一个仲裁者来在竞争的数据节点组之间做出决定。当至少一个节点组中的所有数据节点都存活时,网络分区就不是问题,因为没有单个子集可以独立形成一个功能性集群。真正的问题是当没有一个节点组的所有节点都存活时,这种情况下网络分区(“脑裂”场景)就可能发生。然后需要一个仲裁者。所有集群节点都将同一个节点识别为仲裁者,通常是管理服务器;但是,也可以配置集群中的任何 MySQL 服务器来充当仲裁者。仲裁者接受首先联系到它的一组集群节点,并告诉其余的集群节点关闭。仲裁者的选择由 MySQL 服务器和管理服务器节点的ArbitrationRank配置参数控制。您还可以使用ArbitrationRank配置参数来控制仲裁者选择过程。有关这些参数的更多信息,请参见第 25.4.3.5 节,“定义 NDB 集群管理服务器”。仲裁者的角色本身并不对指定的主机施加任何重大要求,因此仲裁者主机不需要特别快速或为此目的特别增加内存。
A.10.30.NDB Cluster 支持哪些数据类型?

| | NDB Cluster 支持所有常见的 MySQL 数据类型,包括与 MySQL 的空间扩展相关的数据类型;但是,NDB存储引擎不支持空间索引。(空间索引仅由MyISAM支持;有关更多信息,请参见第 13.4 节,“空间数据类型”。此外,当与NDB表一起使用时,索引存在一些差异。注意

NDB Cluster Disk Data 表(即使用 TABLESPACE ... STORAGE DISK ENGINE=NDBTABLESPACE ... STORAGE DISK ENGINE=NDBCLUSTER 创建的表)仅具有固定宽度的行。这意味着(例如)每个包含 VARCHAR(255) 列的 Disk Data 表记录需要为 255 个字符(根据表使用的字符集和校对规则所需的字符数)留出空间,而不管其中实际存储的字符数。

有关这些问题的更多信息,请参见第 25.2.7 节,“NDB Cluster 的已知限制”。

A.10.31.如何启动和停止 NDB Cluster?

| | 必须按以下顺序分别启动集群中的每个节点:

  1. 使用ndb_mgmd命令启动管理节点。

    当首次启动集群时,必须包含-f--config-file选项,告诉管理节点其配置文件的位置。

  2. 使用ndbd命令启动每个数据节点。

    每个数据节点必须使用-c--ndb-connectstring选项启动,以便数据节点知道如何连接到管理服务器。

  3. 使用您喜欢的启动脚本(如mysqld_safe)启动每个 MySQL 服务器(SQL 节点)。

    每个 MySQL 服务器必须使用--ndbcluster--ndb-connectstring选项启动。这些选项使mysqld启用NDBCLUSTER存储引擎支持,并指定如何连接到管理服务器。

每个这些命令必须从承载受影响节点的机器的系统 shell 中运行。(您不必亲自在机器上,可以使用远程登录 shell 来完成此操作。)您可以通过在承载管理节点的机器上启动NDB管理客户端ndb_mgm并发出SHOWALL STATUS命令来验证集群是否正在运行。要关闭正在运行的集群,请在管理客户端中发出SHUTDOWN命令。或者,您可以在系统 shell 中输入以下命令:

$> ndb_mgm -e "SHUTDOWN"

(在此示例中,引号是可选的,因为在 -e 选项后面的命令字符串中没有空格;此外,SHUTDOWN命令(像其他管理客户端命令一样)不区分大小写。)这两个命令都会导致ndb_mgmndb_mgm和任何ndbd进程优雅地终止。作为 SQL 节点运行的 MySQL 服务器可以使用mysqladmin shutdown停止。有关更多信息,请参阅第 25.6.1 节,“NDB 集群管理客户端中的命令”和第 25.3.6 节,“NDB 集群的安全关闭和重启”。MySQL 集群管理器提供了处理 NDB 集群节点启动和停止的其他方法。有关此工具的更多信息,请参阅 MySQL 集群管理器 8.0.36 用户手册。 |

A.10.32.当集群关闭时,NDB 集群数据会发生什么?
集群数据节点在内存中保存的数据被写入磁盘,并在下次启动集群时重新加载到内存中。
A.10.33.在 NDB 集群中是否有多个管理节点是个好主意?
它可以作为故障安全的辅助手段。在任何给定时间,只有一个管理节点控制集群,但可以配置一个管理节点作为主节点,以及一个或多个额外的管理节点在主管理节点发生故障时接管。请参阅第 25.4.3 节,“NDB 集群配置文件”,了解如何配置 NDB 集群管理节点的信息。
A.10.34.我可以在一个 NDB 集群中混合不同类型的硬件和操作系统吗?
是的,只要所有机器和操作系统具有相同的“字节序”(全部大端或全部小端)。还可以在不同节点上使用不同 NDB 集群版本的软件。但是,我们仅支持此类用法作为滚动升级过程的一部分(请参见第 25.6.5 节,“执行 NDB 集群的滚动重启”)。
A.10.35.我可以在单个主机上运行两个数据节点吗?两个 SQL 节点?
是的,可以这样做。在多个数据节点的情况下,建议(但不是必须)每个节点使用不同的数据目录。如果要在一台机器上运行多个 SQL 节点,mysqld的每个实例必须使用不同的 TCP/IP 端口。在同一主机上同时运行数据节点和 SQL 节点是可能的,但您应该知道ndbdndbmtd进程可能会与mysqld竞争内存。
A.10.36.我可以在 NDB 集群中使用主机名吗?
是的,可以使用 DNS 和 DHCP 来为集群主机提供服务。但是,如果您的应用程序需要“五个九”可用性,您应该使用固定(数字)IP 地址,因为使集群主机之间的通信依赖于 DNS 和 DHCP 等服务会引入额外的潜在故障点。
A.10.37.NDB 集群支持 IPv6 吗?
SQL 节点(MySQL 服务器)之间支持 IPv6 连接,但所有其他类型的 NDB 集群节点之间的连接必须使用 IPv4。实际上,这意味着您可以在 NDB 集群之间使用 IPv6 进行复制,但同一 NDB 集群中的节点之间的连接必须使用 IPv4。有关更多信息,请参见第 25.7.3 节,“NDB 集群复制中的已知问题”。
A.10.38.如何处理在具有多个 MySQL 服务器的 NDB 集群中的 MySQL 用户?
MySQL 用户帐户和权限通常不会在访问同一 NDB 集群的不同 MySQL 服务器之间自动传播。MySQL NDB 集群通过NDB_STORED_USER权限提供对共享和同步用户和权限的支持;有关更多信息,请参见使用共享授权表进行分布式权限。您应该知道,此实现是在 NDB 8.0 中引入的,与 NDB 集群早期版本中使用的共享权限机制不兼容。旧的实现在 NDB 8.0 中不再受支持。
A.10.39.如果 SQL 节点之一失败,我如何继续发送查询?
MySQL NDB 集群不提供任何自动故障转移功能,以在 SQL 节点之间进行故障转移。您的应用程序必须准备好处理 SQL 节点的丢失并在它们之间进行故障转移。
A.10.40.如何备份和恢复 NDB 集群?
您可以在 NDB 管理客户端和 ndb_restore 程序中使用 NDB 集群的本地备份和恢复功能。请参阅 第 25.6.8 节,“NDB 集群的在线备份”,以及 第 25.5.23 节,“ndb_restore — 恢复 NDB 集群备份”。您还可以使用传统功能提供的功能在 mysqldump 和 MySQL 服务器中进行此操作。有关更多信息,请参阅 第 6.5.4 节,“mysqldump — 数据库备份程序”。
A.10.41.什么是“天使进程”?

| | 此进程监视并在必要时尝试重新启动数据节点进程。如果在启动 ndbd 后检查系统上的活动进程列表,您会看到实际上有 2 个同名进程正在运行,如下所示(为简洁起见,我们省略了 ndb_mgmdndbd 的输出): |

$> ./ndb_mgmd

$> ps aux | grep ndb
me      23002  0.0  0.0 122948  3104 ?        Ssl  14:14   0:00 ./ndb_mgmd
me      23025  0.0  0.0   5284   820 pts/2    S+   14:14   0:00 grep ndb

$> ./ndbd -c 127.0.0.1 --initial

$> ps aux | grep ndb
me      23002  0.0  0.0 123080  3356 ?        Ssl  14:14   0:00 ./ndb_mgmd
me      23096  0.0  0.0  35876  2036 ?        Ss   14:14   0:00 ./ndbmtd -c 127.0.0.1 --initial
me      23097  1.0  2.4 524116 91096 ?        Sl   14:14   0:00 ./ndbmtd -c 127.0.0.1 --initial
me      23168  0.0  0.0   5284   812 pts/2    R+   14:15   0:00 grep ndb

显示内存和 CPU 使用率均为 0.0ndbd 进程是天使进程(尽管实际上确实会使用很少量的内存和 CPU)。此进程仅检查主要的 ndbdndbmtd") 进程(实际处理数据的主要数据节点进程)是否正在运行。如果允许(例如,如果 StopOnError 配置参数设置为 false),天使进程会尝试重新启动主要数据节点进程。 |

A.11 MySQL 8.0 FAQ:MySQL 中文、日文和韩文字符集

原文:dev.mysql.com/doc/refman/8.0/en/faqs-cjk.html

这组常见问题来源于 MySQL 支持和开发团队处理许多关于 CJK(中文-日文-韩文)问题的经验。

A.11.1. MySQL 中有哪些 CJK 字符集可用?

A.11.2. 我已经将 CJK 字符插入到我的表中。为什么 SELECT 显示它们为“?”字符?

A.11.3. 在使用 Big5 中文字符集时应注意哪些问题?

A.11.4. 为什么日文字符集转换失败?

A.11.5. 如果我想将 SJIS 81CA 转换为 cp932,我该怎么办?

A.11.6. MySQL 如何表示日元(¥)符号?

A.11.7. 在 MySQL 中使用韩文字符集时应注意哪些问题?

A.11.8. 为什么会出现“Incorrect string value”错误消息?

A.11.9. 为什么我的 GUI 前端或浏览器在使用 Access、PHP 或其他 API 的应用程序中不正确显示 CJK 字符?

A.11.10. 我已升级到 MySQL 8.0。如何恢复到 MySQL 4.0 中关于字符集的行为?

A.11.11. 为什么一些带有 CJK 字符的 LIKE 和 FULLTEXT 搜索失败?

A.11.12. 如何知道字符 X 是否在所有字符集中都可用?

A.11.13. 为什么在 Unicode 中 CJK 字符串排序不正确?(I)

A.11.14. 为什么在 Unicode 中 CJK 字符串排序不正确?(II)

A.11.15. 为什么我的补充字符被 MySQL 拒绝?

A.11.16. “CJK” 应该是“CJKV”吗?

A.11.17. MySQL 允许在数据库和表名中使用 CJK 字符吗?

A.11.18. 在哪里可以找到 MySQL 手册的中文、日文和韩文翻译?

A.11.19. 在 MySQL 中如何获取有关 CJK 和相关问题的帮助?

A.11.1.MySQL 中有哪些 CJK 字符集可用?

| | CJK 字符集的列表可能会根据您的 MySQL 版本而有所不同。例如,gb18030字符集在 MySQL 5.7.4 之前不受支持。然而,由于适用语言的名称出现在INFORMATION_SCHEMA.CHARACTER_SETS表中的DESCRIPTION列中,您可以使用此查询获取所有非 Unicode CJK 字符集的当前列表:

mysql> SELECT CHARACTER_SET_NAME, DESCRIPTION
       FROM INFORMATION_SCHEMA.CHARACTER_SETS
       WHERE DESCRIPTION LIKE '%Chin%'
       OR DESCRIPTION LIKE '%Japanese%'
       OR DESCRIPTION LIKE '%Korean%'
       ORDER BY CHARACTER_SET_NAME;
+--------------------+---------------------------------+
| CHARACTER_SET_NAME | DESCRIPTION                     |
+--------------------+---------------------------------+
| big5               | Big5 Traditional Chinese        |
| cp932              | SJIS for Windows Japanese       |
| eucjpms            | UJIS for Windows Japanese       |
| euckr              | EUC-KR Korean                   |
| gb18030            | China National Standard GB18030 |
| gb2312             | GB2312 Simplified Chinese       |
| gbk                | GBK Simplified Chinese          |
| sjis               | Shift-JIS Japanese              |
| ujis               | EUC-JP Japanese                 |
+--------------------+---------------------------------+

(更多信息,请参阅第 28.3.4 节,“INFORMATION_SCHEMA CHARACTER_SETS 表”。)MySQL 支持三种 GB(国家标准简体中文)字符集的变体,这在中华人民共和国是官方的:gb2312gbk和(自 MySQL 5.7.4 起)gb18030。有时人们尝试将gbk字符插入gb2312,大多数情况下都可以成功,因为gbkgb2312的超集。但最终他们尝试插入一个更罕见的中文字符,却无法成功。(例如,请参阅 Bug #16072)。在这里,我们试图明确gb2312gbk中哪些字符是合法的,参考官方文件。请在报告gb2312gbk错误之前检查这些参考文献:

也可以在 Unicode 字符集中存储 CJK 字符,尽管可用的排序规则可能不会按您的预期对字符进行排序:

  • utf8ucs2字符集支持 Unicode 基本多语言平面(BMP)中的字符。这些字符的代码点值介于U+0000U+FFFF之间。

  • utf8mb4utf16utf16leutf32字符集支持 BMP 字符,以及位于 BMP 之外的补充字符。补充字符的代码点值介于U+10000U+10FFFF之间。

用于 Unicode 字符集的排序规则决定了对集合中的字符进行排序(即区分)的能力:

  • 基于 Unicode Collation Algorithm(UCA)4.0.0 的排序规则只区分 BMP 字符。

  • 基于 UCA 5.2.0 或 9.0.0 的排序规则区分 BMP 和补充字符。

  • 非 UCA 排序规则可能无法区分所有 Unicode 字符。例如,MySQL 的utf8mb4默认排序规则是utf8mb4_general_ci,只区分 BMP 字符。

此外,区分字符并不等同于按照给定 CJK 语言的约定对其进行排序。目前,MySQL 只有一个 CJK 特定的 UCA 排序规则,即gb18030_unicode_520_ci(需要使用非 Unicode gb18030字符集)。有关 Unicode 排序规则及其区分属性的信息,包括辅助字符的排序属性,请参见第 12.10.1 节,“Unicode 字符集”。

A.11.2.我已经将 CJK 字符插入到我的表中。为什么SELECT显示它们为“?”字符?

| | 这个问题通常是由于 MySQL 中的设置与应用程序或操作系统的设置不匹配。以下是纠正这些问题的一些常见步骤:

  • 确保您正在使用的 MySQL 版本

    使用语句SELECT VERSION();来确定这一点。

  • 确保数据库实际上正在使用所需的字符集

    人们经常认为客户端字符集总是与服务器字符集或用于显示目的的字符集相同。然而,这两者都是错误的假设。您可以通过检查SHOW CREATE TABLE *tablename*的结果或更好地使用以下语句来确保:

    SELECT character_set_name, collation_name
        FROM information_schema.columns
        WHERE table_schema = your_database_name
            AND table_name = your_table_name
            AND column_name = your_column_name;
    
  • 确定未正确显示的字符或字符的十六进制值

    您可以使用以下查询在表*table_name中获取列column_name*的此信息:

    SELECT HEX(*column_name*)
    FROM *table_name*;
    

    3F?字符的编码;这意味着?实际上是存储在列中的字符。这通常是由于将特定字符从客户端字符集转换为目标字符集时出现问题而导致的。

  • 确保往返旅程是可能的。当您选择literal(或_introducer hexadecimal-value)时,您是否获得literal作为结果

    例如,日文片假名字符Peペ')存在于所有 CJK 字符集中,并且具有十六进制编码的代码点值0x30da。要测试此字符的往返旅程,请使用以下查询:

    SELECT 'ペ' AS ``;         /* or SELECT _ucs2 0x30da; */
    

    如果结果不是,则往返旅程失败。

    对于关于此类失败的错误报告,我们可能会要求您跟进SELECT HEX('ペ');。然后我们可以确定客户端编码是否正确。

  • 确保问题不是由浏览器或其他应用程序引起的,而不是由 MySQL 引起的

    使用mysql客户端程序来完成此任务。如果mysql正确显示字符,但您的应用程序没有显示正确,那么您的问题可能是由于系统设置引起的。

    要确定您的设置,请使用SHOW VARIABLES语句,其输出应类似于所示内容:

    mysql> SHOW VARIABLES LIKE 'char%';
    +--------------------------+----------------------------------------+
    | Variable_name            | Value                                  |
    +--------------------------+----------------------------------------+
    | character_set_client     | utf8                                   |
    | character_set_connection | utf8                                   |
    | character_set_database   | latin1                                 |
    | character_set_filesystem | binary                                 |
    | character_set_results    | utf8                                   |
    | character_set_server     | latin1                                 |
    | character_set_system     | utf8                                   |
    | character_sets_dir       | /usr/local/mysql/share/mysql/charsets/ |
    +--------------------------+----------------------------------------+
    

    这些是面向国际客户的典型字符集设置(请注意使用utf8 Unicode)连接到西方服务器(latin1是西欧字符集)。

    尽管 Unicode(通常在 Unix 上是utf8变体,在 Windows 上是ucs2变体)优于 Latin,但通常不是您的操作系统实用程序最好支持的。许多 Windows 用户发现,例如对于日本 Windows,使用 Microsoft 字符集,如cp932,是合适的。

    如果您无法控制服务器设置,并且不知道底层计算机使用的设置,请尝试切换到您所在国家的常见字符集(euckr = 韩国;gb18030gb2312gbk = 中华人民共和国;big5 = 台湾;sjisujiscp932eucjpms = 日本;ucs2utf8 = 任何地方)。通常只需要更改客户端、连接和结果设置。SET NAMES语句可以同时更改这三个设置。例如:

    SET NAMES 'big5';
    

    一旦设置正确,您可以通过编辑my.cnfmy.ini使其永久化。例如,您可以添加类似以下内容的行:

    [mysqld]
    character-set-server=big5
    [client]
    default-character-set=big5
    

    可能还存在与应用程序中使用的 API 配置设置有关的问题;有关更多信息,请参阅为什么我的 GUI 前端或浏览器无法正确显示 CJK 字符…?

|

A.11.3.在使用 Big5 中文字符集时应该注意哪些问题?
MySQL 支持在香港和台湾(中华民国)常见的 Big5 字符集。MySQL 的big5字符集实际上是 Microsoft 的代码页 950,与原始的big5字符集非常相似。已经提出了添加HKSCS扩展的功能请求。需要此扩展的人可能会对 Bug#13577 的建议补丁感兴趣。
A.11.4.为什么日文字符集转换会失败?

| | MySQL 支持sjisujiscp932eucjpms字符集,以及 Unicode。常见的需求是在字符集之间进行转换。例如,可能有一个 Unix 服务器(通常使用sjisujis)和一个 Windows 客户端(通常使用cp932)。在下表中,ucs2列代表源,而sjiscp932ujiseucjpms列代表目的地;也就是说,最后 4 列提供了当我们使用CONVERT(ucs2)或将包含该值的ucs2列分配给sjiscp932ujiseucjpms列时的十六进制结果。

| 字符名称 | ucs2 | sjis | cp932 | ujis | eucjpms |

| 破折号 | 00A6 | 3F | 3F | 8FA2C3 | 3F |

| 全角破折号 | FFE4 | 3F | FA55 | 3F | 8FA2 |

| 日元符号 | 00A5 | 3F | 3F | 20 | 3F |

| 全角日元符号 | FFE5 | 818F | 818F | A1EF | 3F |

| 波浪线 | 007E | 7E | 7E | 7E | 7E |

| 上划线 | 203E | 3F | 3F | 20 | 3F |

| 横线 | 2015 | 815C | 815C | A1BD | A1BD |

| 破折号 | 2014 | 3F | 3F | 3F | 3F |

| 反斜线 | 005C | 815F | 5C | 5C | 5C |

| 全角反斜线 | FF3C | 3F | 815F | 3F | A1C0 |

| 波浪破折号 | 301C | 8160 | 3F | A1C1 | 3F |

| 全角波浪线 | FF5E | 3F | 8160 | 3F | A1C1 |

| 双竖线 | 2016 | 8161 | 3F | A1C2 | 3F |

| 平行于 | 2225 | 3F | 8161 | 3F | A1C2 |

| 减号符号 | 2212 | 817C | 3F | A1DD | 3F |

| 全角连字符 | FF0D | 3F | 817C | 3F | A1DD |

| 分币符号 | 00A2 | 8191 | 3F | A1F1 | 3F |

| 全角分币符号 | FFE0 | 3F | 8191 | 3F | A1F1 |

| 英镑符号 | 00A3 | 8192 | 3F | A1F2 | 3F |

| 全角英镑符号 | FFE1 | 3F | 8192 | 3F | A1F2 |

| 非逻辑非符 | 00AC | 81CA | 3F | A2CC | 3F |

| 全角非逻辑非符 | FFE2 | 3F | 81CA | 3F | A2CC |

| 字符名称 | ucs2 | sjis | cp932 | ujis | eucjpms |

现在考虑表格的以下部分。

| | ucs2 | sjis | cp932 |

| 非逻辑非符 | 00AC | 81CA | 3F |

| 全角非逻辑非符 | FFE2 | 3F | 81CA |

这意味着 MySQL 将非逻辑非符(Unicode U+00AC)转换为sjis代码点0x81CA,转换为cp932代码点3F。(3F是问号(“?”)。这是在无法执行转换时始终使用的。) |

A.11.5.如果我想将 SJIS 81CA 转换为 cp932,我应该怎么做?
我们的答案是:“?”。这样做有缺点,许多人更喜欢“宽松”转换,这样sjis中的81CA(非逻辑非符)就会变成cp932中的81CA(全角非逻辑非符)
A.11.6.MySQL 如何表示日元(¥)符号?
一个问题出现在于一些版本的日文字符集(sjiseuc)将5C视为反斜杠(\,也称为反斜线),而其他版本将其视为日元符号(¥)。MySQL 遵循 JIS(日本工业标准)标准描述的一个版本。在 MySQL 中,5C始终是反斜杠(\)
A.11.7.在 MySQL 中使用韩文字符集时应注意哪些问题?

| 理论上,虽然有几个版本的euckr(扩展 Unix 代码韩国)字符集,但只有一个问题被指出。我们使用“ASCII”变体的 EUC-KR,其中代码点0x5c是反斜杠,即\,而不是“KS-Roman”变体的 EUC-KR,其中代码点0x5cWON SIGN(₩)。这意味着你无法将 Unicode U+20A9转换为euckr

mysql> SELECT
           CONVERT('₩' USING euckr) AS euckr,
           HEX(CONVERT('₩' USING euckr)) AS hexeuckr;
+-------+----------+
| euckr | hexeuckr |
+-------+----------+
| ?     | 3F       |
+-------+----------+

|

A.11.8.为什么我会收到不正确的字符串值错误消息?

| | 要查看问题,创建一个具有一个 Unicode(ucs2)列和一个中文(gb2312)列的表。

mysql> CREATE TABLE ch
       (ucs2 CHAR(3) CHARACTER SET ucs2,
       gb2312 CHAR(3) CHARACTER SET gb2312);

在非严格 SQL 模式下,尝试在两列中都放置罕见字符

mysql> SET sql_mode = '';
mysql> INSERT INTO ch VALUES ('A 汌 B','A 汌 B');
Query OK, 1 row affected, 1 warning (0.00 sec)

INSERT产生一个警告。使用以下语句查看是什么:

mysql> SHOW WARNINGS\G
*************************** 1\. row ***************************
  Level: Warning
   Code: 1366
Message: Incorrect string value: '\xE6\xB1\x8CB' for column 'gb2312' at row 1

所以这只是关于gb2312列的警告。

mysql> SELECT ucs2,HEX(ucs2),gb2312,HEX(gb2312) FROM ch;
+-------+--------------+--------+-------------+
| ucs2  | HEX(ucs2)    | gb2312 | HEX(gb2312) |
+-------+--------------+--------+-------------+
| A 汌 B | 00416C4C0042 | A?B    | 413F42      |
+-------+--------------+--------+-------------+

这里有几件事情需要解释:

  1. 如前所述,字符不在gb2312字符集中。

  2. 如果你正在使用旧版本的 MySQL,你可能会看到不同的消息。

  3. 出现警告而不是错误,是因为 MySQL 没有设置为使用严格的 SQL 模式。在非严格模式下,MySQL 会尽力而为,以获得最佳匹配,而不是放弃。在严格的 SQL 模式下,不正确的字符串值消息会作为错误而不是警告出现,INSERT将失败。

|

A.11.9.为什么我的 GUI 前端或浏览器在使用 Access、PHP 或其他 API 的应用程序中不正确显示 CJK 字符?

| | 使用mysql客户端直接连接到服务器,并在那里尝试相同的查询。如果mysql正确响应,问题可能是你的应用程序接口需要初始化。使用mysql告诉你它使用的字符集或字符集的语句SHOW VARIABLES LIKE 'char%';。如果你正在使用 Access,你很可能是通过 Connector/ODBC 连接的。在这种情况下,你应该检查配置 Connector/ODBC。例如,如果你使用big5,你会输入SET NAMES 'big5'。(在这种情况下,不需要字符。)如果你正在使用 ASP,你可能需要在代码中添加SET NAMES。以下是过去有效的示例:

<%
Session.CodePage=0
Dim strConnection
Dim Conn
strConnection="driver={MySQL ODBC 3.51 Driver};server=*server*;uid=*username*;" \
               & "pwd=*password*;database=*database*;stmt=SET NAMES 'big5';"
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open strConnection
%>

同样,如果你在 Connector/NET 中使用除latin1之外的任何字符集,你必须在连接字符串中指定字符集。有关更多信息,请参阅 Connector/NET Connections。如果���正在使用 PHP,尝试这样做:

<?php
  $link = new mysqli($host, $usr, $pwd, $db);

  if( mysqli_connect_errno() )
  {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
  }

  $link->query("SET NAMES 'utf8'");
?>

在这种情况下,我们使用 SET NAMES 来更改 character_set_clientcharacter_set_connectioncharacter_set_results。PHP 应用程序经常遇到的另一个问题与浏览器的假设有关。有时添加或更改 <meta> 标签就足以解决问题:例如,为了确保用户代理将页面内容解释为 UTF-8,在 HTML 页面的 <head> 部分包含 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">。如果您正在使用 Connector/J,请参阅 使用字符集和 Unicode。

A.11.10.我已升级到 MySQL 8.0。如何恢复到 MySQL 4.0 中关于字符集的行为?

| | 在 MySQL 版本 4.0 中,服务器和客户端共用一个“全局”字符集,由服务器管理员决定使用哪种字符集。从 MySQL 版本 4.1 开始,情况发生了变化。现在是一个“握手”过程,如 第 12.4 节,“连接字符集和校对规则” 中所描述的:

当客户端连接时,它会向服务器发送要使用的字符集的名称。服务器使用该名称设置 character_set_clientcharacter_set_resultscharacter_set_connection 系统变量。实际上,服务器使用字符集名称执行 SET NAMES 操作。

这样做的效果是,您无法通过使用--character-set-server=utf8启动mysqld来控制客户端字符集。然而,一些亚洲客户更喜欢 MySQL 4.0 的行为。为了保留这种行为,我们添加了一个mysqld开关,--character-set-client-handshake,可以通过--skip-character-set-client-handshake关闭。如果您使用--skip-character-set-client-handshake启动mysqld,那么当客户端连接时,它会向服务器发送它想要使用的字符集的名称。然而,服务器会忽略客户端的这个请求。举例来说,假设您最喜欢的服务器字符集是latin1。进一步假设客户端使用utf8,因为这是客户端操作系统支持的。以latin1作为默认字符集启动服务器:

mysqld --character-set-server=latin1

然后使用默认字符集utf8启动客户端:

mysql --default-character-set=utf8

可以通过查看SHOW VARIABLES的输出来查看结果设置:

mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------------------+
&#124; Variable_name            &#124; Value                                  &#124;
+--------------------------+----------------------------------------+
&#124; character_set_client     &#124; utf8                                   &#124;
&#124; character_set_connection &#124; utf8                                   &#124;
&#124; character_set_database   &#124; latin1                                 &#124;
&#124; character_set_filesystem &#124; binary                                 &#124;
&#124; character_set_results    &#124; utf8                                   &#124;
&#124; character_set_server     &#124; latin1                                 &#124;
&#124; character_set_system     &#124; utf8                                   &#124;
&#124; character_sets_dir       &#124; /usr/local/mysql/share/mysql/charsets/ &#124;
+--------------------------+----------------------------------------+

现在停止客户端,并使用mysqladmin停止服务器。然后再次启动服务器,但这次告诉它跳过握手过程,如下所示:

mysqld --character-set-server=utf8 --skip-character-set-client-handshake

再次将客户端以utf8作为默认字符集启动,然后显示结果设置:

mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------------------+
&#124; Variable_name            &#124; Value                                  &#124;
+--------------------------+----------------------------------------+
&#124; character_set_client     &#124; latin1                                 &#124;
&#124; character_set_connection &#124; latin1                                 &#124;
&#124; character_set_database   &#124; latin1                                 &#124;
&#124; character_set_filesystem &#124; binary                                 &#124;
&#124; character_set_results    &#124; latin1                                 &#124;
&#124; character_set_server     &#124; latin1                                 &#124;
&#124; character_set_system     &#124; utf8                                   &#124;
&#124; character_sets_dir       &#124; /usr/local/mysql/share/mysql/charsets/ &#124;
+--------------------------+----------------------------------------+

通过比较SHOW VARIABLES的不同结果,可以看到如果使用--skip-character-set-client-handshake选项,服务器会忽略客户端的初始设置。|

A.11.11.为什么一些带有 CJK 字符的LIKEFULLTEXT搜索会失败?

| | 对于LIKE搜索,像BINARYBLOB这样的二进制字符串列类型存在一个非常简单的问题:我们必须知道字符的结束位置。在多字节字符集中,不同的字符可能具有不同的八位字节长度。例如,在utf8中,A需要一个字节,但需要三个字节,如下所示:

+-------------------------+---------------------------+
&#124; OCTET_LENGTH(_utf8 'A') &#124; OCTET_LENGTH(_utf8 'ペ') &#124;
+-------------------------+---------------------------+
&#124;                       1 &#124;                         3 &#124;
+-------------------------+---------------------------+

如果我们不知道字符串中第一个字符的结束位置,那么我们也不知道第二个字符从哪里开始,这种情况下,即使是非常简单的搜索,比如LIKE '_A%'也会失败。解决方法是使用定义为具有适当 CJK 字符集的非二进制字符串列类型。例如:mycol TEXT CHARACTER SET sjis。或者,在比较之前转换为 CJK 字符集。这也是 MySQL 不能允许不存在字符的编码的原因之一。如果不严格拒绝错误输入,MySQL 就无法知道字符的结束位置。对于FULLTEXT搜索,我们必须知道单词的起始和结束位置。对于西方语言,这很少是问题,因为大多数(如果不是全部)都使用易于识别的单词边界:空格字符。然而,对于亚洲文字通常不是这种情况。我们可以使用任意的中间措施,比如假设所有汉字代表单词,或者(对于日语)依赖于片假名到平假名的变化,因为语法结尾。然而,唯一确定的解决方案需要一个全面的单词列表,这意味着我们必须为每种支持的亚洲语言在服务器中包含一个字典。这根本不可行。

A.11.12.我如何知道字符*X*在所有字符集中是否可用?

| | 大多数简体中文和基本非半角宽日语假名字符出现在所有 CJK 字符集中。以下存储过程接受一个UCS-2 Unicode 字符,将其转换为其他字符集,并以十六进制显示结果。

DELIMITER //

CREATE PROCEDURE p_convert(ucs2_char CHAR(1) CHARACTER SET ucs2)
BEGIN

CREATE TABLE tj
             (ucs2 CHAR(1) character set ucs2,
              utf8 CHAR(1) character set utf8,
              big5 CHAR(1) character set big5,
              cp932 CHAR(1) character set cp932,
              eucjpms CHAR(1) character set eucjpms,
              euckr CHAR(1) character set euckr,
              gb2312 CHAR(1) character set gb2312,
              gbk CHAR(1) character set gbk,
              sjis CHAR(1) character set sjis,
              ujis CHAR(1) character set ujis);

INSERT INTO tj (ucs2) VALUES (ucs2_char);

UPDATE tj SET utf8=ucs2,
              big5=ucs2,
              cp932=ucs2,
              eucjpms=ucs2,
              euckr=ucs2,
              gb2312=ucs2,
              gbk=ucs2,
              sjis=ucs2,
              ujis=ucs2;

/* If there are conversion problems, UPDATE produces warnings. */

SELECT hex(ucs2) AS ucs2,
       hex(utf8) AS utf8,
       hex(big5) AS big5,
       hex(cp932) AS cp932,
       hex(eucjpms) AS eucjpms,
       hex(euckr) AS euckr,
       hex(gb2312) AS gb2312,
       hex(gbk) AS gbk,
       hex(sjis) AS sjis,
       hex(ujis) AS ujis
FROM tj;

DROP TABLE tj;

END//

DELIMITER ;

输入可以是任何单个ucs2字符,或者可以是该字符的代码值(十六进制表示)。例如,从 Unicode 的ucs2编码和名称列表(www.unicode.org/Public/UNIDATA/UnicodeData.txt)中,我们知道片假名字符Pe出现在所有 CJK 字符集中,并且其代码值为X'30DA'。如果我们将这个值作为p_convert()的参数,结果如下所示:

mysql> CALL p_convert(X'30DA');
+------+--------+------+-------+---------+-------+--------+------+------+------+
&#124; ucs2 &#124; utf8   &#124; big5 &#124; cp932 &#124; eucjpms &#124; euckr &#124; gb2312 &#124; gbk  &#124; sjis &#124; ujis &#124;
+------+--------+------+-------+---------+-------+--------+------+------+------+
&#124; 30DA &#124; E3839A &#124; C772 &#124; 8379  &#124; A5DA    &#124; ABDA  &#124; A5DA   &#124; A5DA &#124; 8379 &#124; A5DA &#124;
+------+--------+------+-------+---------+-------+--------+------+------+------+

由于列值中没有3F(即问号字符,?),我们知道每次转换都成功了。

A.11.13.为什么 CJK 字符串在 Unicode 中排序不正确?(I)
在 MySQL 8.0 中,可以通过使用utf8mb4字符集和utf8mb4_ja_0900_as_cs校对规则来解决旧版本 MySQL 中出现的 CJK 排序问题。
A.11.14.为什么 CJK 字符串在 Unicode 中排序不正确?(II)
在 MySQL 8.0 中,可以通过使用utf8mb4字符集和utf8mb4_ja_0900_as_cs校对规则来解决旧版本 MySQL 中出现的 CJK 排序问题。
A.11.15.为什么我的补充字符被 MySQL 拒绝?

| | 补充字符位于 Unicode 基本多语言平面/平面 0之外。BMP 字符的代码点值介于U+0000U+FFFF之间。补充字符的代码点值介于U+10000U+10FFFF之间。要存储补充字符,必须使用允许它们的字符集:

  • utf8ucs2字符集仅支持 BMP 字符。

    utf8字符集仅允许占用最多三个字节的UTF-8字符。这导致了 Bug #12600 中的报告,我们将其拒绝为“不是一个 bug”。使用utf8时,MySQL 在遇到无法理解的字节时必须截断输入字符串。否则,无法确定坏的多字节字符有多长。

    一个可能的解决方法是使用ucs2代替utf8,在这种情况下,“坏”字符会被更改为问号。但是,不会发生截断。您还可以将数据类型更改为BLOBBINARY,这些类型不执行有效性检查。

  • utf8mb4utf16utf16leutf32字符集支持 BMP 字符,以及 BMP 之外的补充字符。

|

A.11.16.“CJK”应该改为“CJKV”吗?
不。术语“CJKV”(中文、日文、韩文、越南文)指的是包含汉字(最初是中文)字符的越南字符集。MySQL 支持带有西方字符的现代越南文脚本,但不支持使用汉字字符的旧越南文脚本。截至 MySQL 5.6,有适用于 Unicode 字符集的越南文排序规则,如第 12.10.1 节“Unicode 字符集”所述。
A.11.17.MySQL 允许在数据库和表名中使用 CJK 字符吗?
是的。
A.11.18.我在哪里可以找到 MySQL 手册的中文、日文和韩文翻译?
MySQL 5.6 手册的日文翻译可从dev.mysql.com/doc/下载。
A.11.19.我在哪里可以获取有关 MySQL 中 CJK 和相关问题的帮助?

| | 以下资源可供使用:

|

A.12 MySQL 8.0 常见问题解答:连接器和 API

原文:dev.mysql.com/doc/refman/8.0/en/faqs-connectors-apis.html

关于 MySQL 连接器和其他 API 的常见问题、问题和答案,请参阅手册的以下部分:

  • 使用 C API 功能

  • Connector/ODBC 注意事项和提示

  • Connector/NET 编程

  • MySQL Connector/J 8.0 开发人员指南

A.13 MySQL 8.0 FAQ:C API,libmysql

原文:dev.mysql.com/doc/refman/8.0/en/faqs-c-api.html

关于 MySQL C API 和 libmysql 的常见问题。

A.13.1. 什么是“MySQL 原生 C API”?典型的优势和用例是什么?

A.13.2. 我应该使用哪个版本的 libmysql?

A.13.3. 如果我想使用“NoSQL” X DevAPI 怎么办?

A.13.4. 如何下载 libmysql?

A.13.5. 文档在哪里?

A.13.6. 如何报告错误?

A.13.7. 是否可以自己编译库?

A.13.1.什么是“MySQL 原生 C API”?典型的优势和用例是什么?
libmysql 是一个基于 C 的 API,您可以在 C 应用程序中使用它与 MySQL 数据库服务器连接。它本身也被用作标准数据库 API(如 ODBC、Perl 的 DBI 和 Python 的 DB API)驱动程序的基础。
A.13.2.我应该使用哪个版本的 libmysql?
对于 MySQL 8.0、5.7、5.6 和 5.5,我们推荐使用 libmysql 8.0。
A.13.3.如果我想使用“NoSQL” X DevAPI 怎么办?
对于 MySQL 8.0 的 C 语言和 X DevApi 文档存储,我们推荐使用 MySQL Connector/C++。Connector/C++ 8.0 具有兼容的 C 头文件。(这不适用于 MySQL 5.7 或更早版本。)
A.13.4.如何下载 libmysql?

|

A.13.5.文档在哪里?
参阅 MySQL 8.0 C API 开发人员指南。
A.13.6.如何报告错误?
请向我们的Bugs Database报告您观察到的任何错误或不一致性。选择如图所示的 C API 客户端。
A.13.7.是否可以自己编译库?
编译 MySQL Server 也会编译 libmysqlclient;没有办法只编译 libmysqlclient。有关相关信息,请参阅 MySQL C API 实现。

A.14 MySQL 8.0 FAQ: 复制

原文:dev.mysql.com/doc/refman/8.0/en/faqs-replication.html

在接下来的部分中,我们提供关于 MySQL 复制最常见问题的答案。

A.14.1. 副本必须始终连接到源吗?

A.14.2. 必须在源和副本上启用网络才能启用复制吗?

A.14.3. 如何知道副本相对于源有多晚?换句话说,如何知道副本复制的最后一个语句的日期?

A.14.4. 如何强制源阻止更新,直到副本赶上?

A.14.5. 设置双向复制时应注意的问题

A.14.6. 如何利用复制来提高系统性能?

A.14.7. 我应该如何准备自己应用程序中的客户端代码以使用性能增强的复制?

A.14.8. MySQL 复制何时以及在多大程度上可以提高系统性能?

A.14.9. 如何利用复制提供冗余或高可用性?

A.14.10. 如何确定复制源服务器是使用基于语句还是基于行的二进制日志格式?

A.14.11. 如何告诉副本使用基于行的复制?

A.14.12. 如何防止 GRANT 和 REVOKE 语句复制到副本机器?

A.14.13. 复制是否适用于混合操作系统(例如,源在 Linux 上运行,而副本在 macOS 和 Windows 上运行)?

A.14.14. 复制是否适用于混合硬件架构(例如,源在 64 位机器上运行,而副本在 32 位机器上运行)?

A.14.1.副本必须始终连接到源吗?
不,它不会。复制品可以在几个小时甚至几天内断开连接,然后重新连接并赶上更新。例如,您可以在仅偶尔连接且连接时间很短的拨号链接上建立源/复制品关系。这意味着,在任何给定时间,除非您采取一些特殊措施,否则不能保证复制品与源同步。为了确保断开连接的复制品可以进行追赶,您不能从包含尚未复制到复制品的信息的源中删除二进制日志文件。异步复制只有在复制品能够从上次读取事件的地方继续读取二进制日志时才能工作。
A.14.2.我必须在源和复制品上启用网络才能启用复制吗?
是的,必须在源和复制品上启用网络。如果未启用网络,则复制品无法连接到源并传输二进制日志。请验证配置文件中未启用skip_networking系统变量。
A.14.3.我如何知道复制品相对于源有多晚?换句话说,我如何知道复制品复制的最后一个语句的日期?
SHOW REPLICA &#124; SLAVE STATUS的输出中检查Seconds_Behind_Master列。参见 Section 19.1.7.1,“检查复制状态”。当复制 SQL 线程执行从源读取的事件时,它会将自己的时间修改为事件时间戳。(这就是为什么TIMESTAMP很好地复制。)在SHOW PROCESSLIST的输出中的Time列中,复制 SQL 线程显示的秒数是最后一个复制事件的时间戳与复制品机器的实际时间之间的秒数。您可以使用此来确定最后一个复制事件的日期。请注意,如果您的复制品与源断开连接了一个小时,然后重新连接,您可能会立即看到大的Time值,例如在SHOW PROCESSLIST中的复制 SQL 线程为 3600。这是因为复制品正在执行一个小时前的语句。参见 Section 19.2.3,“复制线程”。
A.14.4.我如何强制源阻止更新直到复制品赶上?

| | 使用以下步骤:

  1. 在源上执行以下语句:

    mysql> FLUSH TABLES WITH READ LOCK;
    mysql> SHOW MASTER STATUS;
    

    记录从SHOW语句的输出中获取的复制坐标(当前二进制日志文件名和位置)。

  2. 在复制品上,发出以下语句,其中SOURCE_POS_WAIT()MASTER_POS_WAIT()函数的参数是在上一步中获取的复制坐标值:

    mysql> SELECT MASTER_POS_WAIT('*log_name*', *log_pos*);
    
    Or from MySQL 8.0.26:
    mysql> SELECT SOURCE_POS_WAIT('*log_name*', *log_pos*);
    

    SELECT 语句会阻塞,直到复制品达到指定的日志文件和位置。在那一点上,复制品与源头同步,语句返回。

  3. 在源头上,发出以下语句以使源头能够再次开始处理更新:

    mysql> UNLOCK TABLES;
    

|

A.14.5.在设置双向复制时我应该注意哪些问题?
MySQL 复制目前不支持源头和复制品之间的任何锁定协议,以保证分布式(跨服务器)更新的原子性。换句话说,客户端 A 可能会对共源 1 进行更新,同时,在它传播到共源 2 之前,客户端 B 可能会对共源 2 进行更新,使得客户端 A 的更新在共源 1 上的工作方式与共源 2 上的工作方式不同。因此,当客户端 A 的更新到达共源 2 时,它生成的表与您在共源 1 上拥有的表不同,即使所有来自共源 2 的更新也已传播。这意味着您不应该将两个服务器链接在一起形成双向复制关系,除非您确信您的更新可以安全地以任何顺序发生,或者除非您在客户端代码中以某种方式处理错误排序的更新。您还应该意识到,双向复制实际上在更新方面并没有多大(如果有的话)性能提升。每个服务器必须执行相同数量的更新,就像您只有一个服务器执行一样。唯一的区别是,由于来自另一个服务器的更新在一个复制线程中串行化,因此锁定争用会少一点。即使这种好处可能会被网络延迟抵消。
A.14.6.我如何利用复制来提高系统性能?
将一个服务器设置为源服务器,并将所有写操作定向到该服务器。然后配置尽可能多的副本,以适应预算和机架空间,并在源服务器和副本之间分配读操作。您还可以使用--skip-innodb选项启动副本,启用low_priority_updates系统变量,并将delay_key_write系统变量设置为ALL,以在副本端获得速度改进。在这种情况下,副本使用非事务性的MyISAM表而不是InnoDB表,通过消除事务开销来获得更快的速度。
A.14.7.我应该如何准备自己应用程序中的客户端代码以使用性能增强的复制?
查看使用复制作为扩展解决方案的指南,第 19.4.5 节,“使用复制进行扩展”。
A.14.8.MySQL 复制何时以及在多大程度上可以提高系统性能?

| | MySQL 复制对于处理频繁读取和不频繁写入的系统最为有益。理论上,通过使用单源/多副本设置,您可以通过添加更多副本来扩展系统,直到您耗尽网络带宽,或者更新负载增长到源服务器无法处理的程度。要确定在增加副本数量之前增加的好处何时开始趋于平稳,以及您可以提高站点性能多少,您必须了解您的查询模式,并通过基准测试确定典型源服务器和典型副本之间读取和写入吞吐量之间的关系。这里的示例展示了对假设系统使用复制可以获得的相当简化的计算。让readswrites分别表示每秒读取和写入的次数。假设系统负载由 10%的写入和 90%的读取组成,并且我们通过基准测试确定reads为 1200 - 2 * writes。换句话说,系统可以在没有写入的情况下每秒进行 1,200 次读取,平均写入速度是平均读取速度的两倍,且关系是线性的。假设源服务器和每个副本具有相同的容量,并且我们有一个源服务器和N个副本。那么对于每台服务器(源服务器或副本):reads = 1200 - 2 * writes``reads = 9 * writes / (N + 1)(读取被分割,但写入被复制到所有副本)9 * writes / (N + 1) + 2 * writes = 1200writes = 1200 / (2 + 9/(N + 1))最后一个方程表示了在N个副本的情况下,给定每秒最大可能的读取速率为 1,200 次和九次读取一次写入的比率,最大写入次数。这个分析得出以下结论:

  • 如果*N* = 0(表示我们没有复制),我们的系统可以处理约 1200/11 = 109 次写入每秒。

  • 如果*N* = 1,我们可以达到每秒 184 次写入。

  • 如果*N* = 8,我们可以达到每秒 400 次写入。

  • 如果*N* = 17,我们可以达到每秒 480 次写入。

  • 最终,当*N*趋近于无穷大(我们的预算趋近于负无穷大)时,我们可以接近每秒 600 次写入,系统吞吐量增加约 5.5 倍。然而,只有八台服务器时,我们将其增加近四倍。

这些计算假定有无限的网络带宽,并忽略了可能在您的系统上具有重要意义的其他几个因素。在许多情况下,您可能无法执行类似于刚刚显示的计算,准确预测如果添加*N*个副本会发生什么。然而,回答以下问题应该帮助您决定复制可能如何以及在多大程度上改善系统性能:

  • 你的系统读写比是多少?

  • 如果减少读取,一个服务器可以处理多少更多的写入负载?

  • 你的网络上有多少副本可以使用带宽?

|

A.14.9.如何使用复制提供冗余或高可用性?
如何实现冗余完全取决于您的应用程序和情况。高可用性解决方案(具有自动故障转移)需要主动监视和自定义脚本或第三方工具来提供从原始 MySQL 服务器到副本的故障转移支持。要手动处理该过程,您应该能够通过修改应用程序以与新服务器通信或通过调整 MySQL 服务器的 DNS 从故障服务器切换到新服务器来切换从失败源到预配置副本。有关更多信息和一些示例解决方案,请参见 Section 19.4.8, “Switching Sources During Failover”。
A.14.10.如何确定复制源服务器是使用基于语句还是基于行的二进制日志格式?

| | 检查binlog_format系统变量的值:

mysql> SHOW VARIABLES LIKE 'binlog_format';

显示的值始终是STATEMENTROWMIXED之一。对于MIXED模式,默认情况下使用基于语句的日志记录,但在某些条件下,例如不安全的语句,复制会自动切换到基于行的日志记录。有关可能发生这种情况的信息,请参见 Section 7.4.4.3, “Mixed Binary Logging Format”。

A.14.11.如何告诉副本使用基于行的复制?
副本自动知道要使用哪种格式。
A.14.12.如何防止GRANTREVOKE语句复制到副本机器?
使用--replicate-wild-ignore-table=mysql.%选项启动服务器,以忽略mysql数据库中的表的复制。
A.14.13.复制是否在混合操作系统上工作(例如,源在 Linux 上运行,而副本在 macOS 和 Windows 上运行)?
是的。
A.14.14.复制是否在混合硬件架构上工作(例如,源在 64 位机器上运行,而副本在 32 位机器上运行)?
是的。

A.15 MySQL 8.0 FAQ: MySQL 企业线程池

原文:dev.mysql.com/doc/refman/8.0/en/faqs-thread-pool.html

A.15.1. 什么是线程池,它解决了什么问题?

A.15.2. 线程池如何限制和管理并发会话和事务,以实现最佳性能和吞吐量?

A.15.3. 线程池与客户端端连接池有何不同?

A.15.4. 何时应该使用线程池?

A.15.5. 有推荐的线程池配置吗?

A.15.1.什么是线程池,它解决了什么问题?
MySQL 线程池是一个 MySQL 服务器插件,扩展了 MySQL 服务器的默认连接处理能力,限制了同时执行的语句/查询和事务的数量,以确保每个都有足够的 CPU 和内存资源来完成其任务。对于 MySQL 8.0,线程池插件包含在 MySQL 企业版中,这是一个商业产品。MySQL 服务器中的默认线程处理模型使用一个线程来执行每个客户端连接的语句。随着更多客户端连接到服务器并执行语句,整体性能会下降。线程池插件提供了一种旨在减少开销并提高性能的替代线程处理模型。线程池插件通过有效地管理大量客户端连接的语句执行线程来提高服务器性能,特别是在现代多 CPU/核心系统上。更多信息,请参见 Section 7.6.3,“MySQL 企业线程池”。
A.15.2.线程池如何限制和管理并发会话和事务,以实现最佳性能和吞吐量?
线程池使用“分而治之”的方法来限制和平衡并发。与 MySQL 服务器的默认连接处理不同,线程池将连接和线程分开,因此连接和执行来自这些连接的语句的线程之间没有固定的关系。然后,线程池在可配置的线程组内管理客户端连接,根据它们被提交以完成的工作的性质进行优先级排序和排队。更多信息,请参见 Section 7.6.3.3,“线程池操作”。
A.15.3.线程池与客户端端连接池有何不同?
MySQL 连接池在客户端上运行,以确保 MySQL 客户端不会不断连接到并断开与 MySQL 服务器的连接。它旨在在 MySQL 客户端中缓存空闲连接,以供其他用户在需要时使用。这最小化了在将查询提交给 MySQL 服务器时建立和拆除连接的开销和费用。MySQL 连接池无法看到后端 MySQL 服务器的查询处理能力或负载。相比之下,线程池在 MySQL 服务器端运行,旨在管理从访问后端 MySQL 数据库的客户端连接接收到的入站并发连接和查询的执行。由于职责的分离,MySQL 连接池和线程池是正交的,可以独立使用。通过 MySQL 连接器进行 MySQL 连接池化在 第三十一章,“连接器和 API” 中有介绍。
A.15.4.我何时应该使用线程池?
有一些经验法则可供考虑以获得最佳的线程池使用情况:MySQL Threads_running 变量跟踪当前在 MySQL 服务器中执行的并发语句数量。如果这个变量持续超过服务器无法正常运行的区域(通常对 InnoDB 工作负载超过 40),线程池应该是有益的,特别是在极端的并行过载情况下。如果您正在使用 innodb_thread_concurrency 来限制同时执行语句的数量,您应该发现线程池解决了同样的问题,只是更好地通过将连接分配给线程组,然后根据事务内容、用户定义的指定等排队执行。最后,如果您的工作负载主要由短查询组成,线程池应该是有益的。要了解更多信息,请参见 第 7.6.3.4 节,“线程池调优”。
A.15.5.是否有推荐的线程池配置?
线程池具有一些用户案例驱动的配置参数,这些参数会影响其性能。要了解这些参数以及调优技巧,请参见 第 7.6.3.4 节,“线程池调优”。

A.16 MySQL 8.0 FAQ:InnoDB 更改缓冲区

原文:dev.mysql.com/doc/refman/8.0/en/faqs-innodb-change-buffer.html

A.16.1. 什么类型的操作会修改辅助索引并导致更改缓冲?

A.16.2. InnoDB 更改缓冲区的好处是什么?

A.16.3. 更改缓冲区支持其他类型的索引吗?

A.16.4. InnoDB 为更改缓冲区使用了多少空间?

A.16.5. 如何确定更改缓冲区的当前大小?

A.16.6. 何时发生更改缓冲区合并?

A.16.7. 何时刷新更改缓冲区?

A.16.8. 何时应该使用更改缓冲区?

A.16.9. 更改缓冲区不应该在什么情况下使用?

A.16.10. 我在哪里可以找到有关更改缓冲区的更多信息?

A.16.1.什么类型的操作会修改辅助索引并导致更改缓冲?
INSERTUPDATEDELETE操作可以修改辅助索引。如果受影响的索引页不在缓冲池中,则更改可以在更改���冲区中缓冲。
A.16.2.InnoDB更改缓冲区的好处是什么?
当辅助索引页不在缓冲池中时,缓冲辅助索引更改可以避免需要立即从磁盘读入受影响的索引页的昂贵随机访问 I/O 操作。缓冲的更改可以稍后批量应用,当页面被其他读取操作读入缓冲池时。
A.16.3.更改缓冲区支持其他类型的索引吗?
不支持更改缓冲区的主键索引。聚簇索引、全文索引和空间索引不受支持。全文索引有自己的缓存机制。
A.16.4.InnoDB为更改缓冲区使用了多少空间?
在 MySQL 5.6 中引入innodb_change_buffer_max_size配置选项之前,系统表空间中磁盘上的变更缓冲的最大大小为InnoDB缓冲池大小的 1/3。在 MySQL 5.6 及更高版本中,innodb_change_buffer_max_size配置选项将变更缓冲的最大大小定义为总缓冲池大小的百分比。默认情况下,innodb_change_buffer_max_size设置为 25。最大设置为 50。如果操作会导致磁盘上的变更缓冲超过定义的限制,则InnoDB不会缓冲该操作。变更缓冲页不需要在缓冲池中持久存在,可能会被 LRU 操作驱逐。
A.16.5.如何确定变更缓冲的当前大小?

| | 变更缓冲的当前大小由SHOW ENGINE INNODB STATUS \G报告,在INSERT BUFFER AND ADAPTIVE HASH INDEX标题下。例如:

-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 0 merges

相关数据点包括:

  • size:变更缓冲中使用的页面数。变更缓冲大小等于seg size - (1 + free list len)1 +值代表变更缓冲头页面。

  • seg size:变更缓冲的大小,以页面为单位。

有关监视变更缓冲状态的信息,请参见 Section 17.5.2,“变更缓冲”。 |

A.16.6.变更缓冲合并发生在什么时候?
  • 当页面被读入缓冲池时,在页面可用之前,缓冲的更改在读取完成后合并。

  • 变更缓冲合并作为后台任务执行。innodb_io_capacity参数设置了InnoDB后台任务(如从变更缓冲合并数据)执行的 I/O 活动的上限。

  • 在崩溃恢复期间执行变更缓冲合并。当索引页面被读入缓冲池时,从变更缓冲(在系统表空间中)应用更改到辅助索引的叶子页面。

  • 变更缓冲是完全持久的,可以在系统崩溃时幸存下来。重新启动后,变更缓冲合并操作将作为正常操作的一部分恢复。

  • 可以通过使用--innodb-fast-shutdown=0在慢速服务器关闭过程中强制执行变更缓冲的完全合并。

|

A.16.7.变更缓冲何时被刷新?
更新的页面由刷新缓冲池中其他页面的相同刷新机制刷新。
A.16.8.何时应该使用变更缓冲?
变更缓冲区是一项旨在减少随着索引变大而无法再适应InnoDB缓冲池而产生的随机 I/O 的功能。通常情况下,当整个数据集无法适应缓冲池时,当有大量修改次要索引页的 DML 活动,或者当有许多次要索引经常被 DML 活动修改时,应该使用变更缓冲区。
A.16.9.何时不应使用变更缓冲区?
如果整个数据集适应InnoDB缓冲池,如果次要索引相对较少,或者如果使用固态存储,其中随机读取速度与顺序读取速度几乎相同,您可能考虑禁用变更缓冲区。在进行配置更改之前,建议您使用代表性工作负载运行测试,以确定禁用变更缓冲区是否提供任何好处。
A.16.10.我在哪里可以找到有关变更缓冲区的更多信息?
参见第 17.5.2 节,“变更缓冲区”。

A.17 MySQL 8.0 FAQ:InnoDB 数据静态加密

原文:dev.mysql.com/doc/refman/8.0/en/faqs-tablespace-encryption.html

A.17.1. 数据是否解密给了有权限查看的用户?

A.17.2. InnoDB 数据静态加密相关的开销是多少?

A.17.3. InnoDB 数据静态加密使用哪些加密算法?

A.17.4. 是否可以使用第三方加密算法代替 InnoDB 数据静态加密功能提供的算法?

A.17.5. 索引列可以加密吗?

A.17.6. InnoDB 数据静态加密支持哪些数据类型和数据长度?

A.17.7. 数据在网络上保持加密吗?

A.17.8. 数据库内存包含明文还是加密数据?

A.17.9. 我如何知道哪些数据需要加密?

A.17.10. InnoDB 数据静态加密与 MySQL 已提供的加密函数有何不同?

A.17.11. 可传输表空间功能与 InnoDB 数据静态加密兼容吗?

A.17.12. 压缩与 InnoDB 数据静态加密是否兼容?

A.17.13. 我可以在加密表上使用 mysqldump 吗?

A.17.14. 如何更改(旋转,重新生成密钥)主加密密钥?

A.17.15. 我如何将数据从明文 InnoDB 表空间迁移到加密的 InnoDB 表空间?

A.17.1.数据是否解密给了有权限查看的用户?
是的。InnoDB数据静态加密旨在在数据库内部透明地应用加密,而不影响现有应用程序。以加密格式返回数据将破坏大多数现有应用程序。InnoDB数据静态加密提供了加密的好处,而不会带来传统数据库加密解决方案所带来的开销,后者通常需要昂贵且重大的应用程序、数据库触发器和视图更改。
A.17.2.InnoDB数据静态加密相关的开销是多少?
没有额外的存储开销。根据内部基准测试,性能开销仅相当于单个数字百分比的差异。
A.17.3.InnoDB数据静态加密使用哪些加密算法?
InnoDB数据静态加密支持高级加密标准(AES256)基于块的加密算法。它使用电子密码本(ECB)块加密模式用于表空间密钥加密,使用密码块链接(CBC)块加密模式用于数据加密。
A.17.4.是否可以使用第三方加密算法来替代InnoDB数据静态加密功能提供的算法?
不,不可能使用其他加密算法。提供的加密算法被广泛接受。
A.17.5.索引列可以加密吗?
InnoDB数据静态加密透明地支持所有索引。
A.17.6.InnoDB数据静态加密支持哪些数据类型和数据长度?
InnoDB数据静态加密支持所有支持的数据类型。没有数据长度限制。
A.17.7.数据在网络上保持加密吗?
通过InnoDB数据静态加密功能加密的数据在从表空间文件读取时解密。因此,如果数据在网络上,它是明文形式。然而,网络上的数据可以使用 MySQL 网络加密进行加密,该加密使用 SSL/TLS 加密数据库之间传输的数据。
A.17.8.数据库内存包含明文还是加密数据?
使用InnoDB数据静态加密,内存中的数据被解密,提供完全透明性。
A.17.9.我如何知道要加密哪些数据?
遵守 PCI-DSS 标准要求信用卡号(主帐号号码,或’PAN’)以加密形式存储。违反通知法律(例如,CA SB 1386,CA AB 1950 以及 43 多个美国州的类似法律)要求对名字、姓氏、驾驶执照号码和其他 PII 数据进行加密。2008 年初,CA AB 1298 将医疗和健康保险信息添加到 PII 数据中。此外,行业特定的隐私和安全标准可能要求对某些资产进行加密。例如,像制药研究结果、油田勘探结果、金融合同或执法线人的个人数据等资产可能需要加密。在医疗保健行业,患者数据、健康记录和 X 射线图像的隐私至关重要。
A.17.10.InnoDB数据静止加密与 MySQL 已提供的加密函数有何不同?
MySQL 中有对称和非对称加密 API,可用于在数据库内部手动加密数据。但是,应用程序必须管理加密密钥,并通过调用 API 函数执行所需的加密和解密操作。InnoDB数据静止加密不需要应用程序更改,对终端用户透明,并提供自动化的内置密钥管理。
A.17.11.可以使用可传输表空间功能与InnoDB数据静止加密一起使用吗?
是的。对于加密的文件表表空间是支持的。有关更多信息,请参见导出加密表空间。
A.17.12.压缩与InnoDB数据静止加密兼容吗?
使用InnoDB数据静止加密的客户可以充分利用压缩,因为压缩是在数据块加密之前应用的。
A.17.13.我可以在加密表上使用mysqldump吗?
是的。因为这些实用程序创建逻辑备份,从加密表中转储的数据未加密。
A.17.14.如何更改(旋转,重新生成)主加密密钥?
InnoDB数据静止加密使用两层密钥机制。当使用数据静止加密时,单独的表空间密钥存储在底层表空间数据文件的头部。表空间密钥使用主加密密钥加密。主加密密钥在启用表空间加密时生成,并存储在数据库外部。主加密密钥使用ALTER INSTANCE ROTATE INNODB MASTER KEY语句进行旋转,生成新的主加密密钥,存储密钥,并将密钥旋转到使用中。
A.17.15.如何将明文InnoDB表空间中的数据迁移到加密InnoDB表空间中?
不需要将数据从一个表空间转移到另一个表空间。要在InnoDB文件每表表空间中加密数据,请运行ALTER TABLE *tbl_name* ENCRYPTION = 'Y'。要加密通用表空间或mysql表空间,请运行ALTER TABLESPACE *tablespace_name* ENCRYPTION = 'Y'。MySQL 8.0.13 引入了对通用表空间的加密支持。MySQL 8.0.16 引入了对mysql系统表空间的加密支持。

A.18 MySQL 8.0 FAQ: 虚拟化支持

原文:dev.mysql.com/doc/refman/8.0/en/faqs-virtualization.html

A.18.1. MySQL 在 Oracle VM、VMWare、Docker、Microsoft Hyper-V 等虚拟化环境中受支持吗?

A.18.1.MySQL 在 Oracle VM、VMWare、Docker、Microsoft Hyper-V 等虚拟化环境中受支持吗?
MySQL 在虚拟化环境中受支持,但仅针对Oracle VM进行了认证。请联系 Oracle 支持获取更多信息。在使用虚拟化软件时要注意潜在问题。通常问题与性能、性能降级、速度慢或磁盘、I/O、网络和内存的不可预测性有关。

附录 B 错误消息和常见问题

原文:dev.mysql.com/doc/refman/8.0/en/error-handling.html

目录

B.1 错误消息来源和元素

B.2 错误信息接口

B.3 问题和常见错误

B.3.1 如何确定问题的原因

B.3.2 使用 MySQL 程序时的常见错误

B.3.3 管理相关问题

B.3.4 查询相关问题

B.3.5 优化器相关问题

B.3.6 表定义相关问题

B.3.7 MySQL 中已知问题

本附录描述了 MySQL 提供的错误信息类型以及如何获取有关它们的信息。最后一节是用于故障排除。它描述了可能发生的常见问题和错误以及可能的解决方法。

其他资源

其他与错误相关的文档包括:

  • 配置服务器写入错误日志的位置和方式的信息:第 7.4.2 节,“错误日志”

  • 关于用于错误消息的字符集的信息:第 12.6 节,“错误消息字符集”

  • 关于错误消息使用的语言的信息:第 12.12 节,“设置错误消息语言”

  • InnoDB相关的错误信息:第 17.21.5 节,“InnoDB 错误处理”

  • 与 NDB 集群特定错误相关的信息:NDB 集群 API 错误;另请参阅 NDB API 错误和错误处理,以及 MGM API 错误

  • MySQL 服务器和客户端程序生成的错误消息描述:MySQL 8.0 错误消息参考

B.1 错误消息来源和元素

原文:dev.mysql.com/doc/refman/8.0/en/error-message-elements.html

本节讨论了 MySQL 内部错误消息的产生方式以及它们包含的元素。

  • 错误消息来源

  • 错误消息元素

  • 错误代码范围

错误消息来源

错误消息可以源自服务器端或客户端端:

  • 在服务器端,错误消息可能发生在启动和关闭过程中,在 SQL 语句执行过程中等。

    • MySQL 服务器将一些错误消息写入其错误日志。这些指示对数据库管理员感兴趣的问题或需要 DBA 操作。

    • 服务器向客户端程序发送其他错误消息。这些指示仅涉及特定客户端的问题。MySQL 客户端库接收来自服务器的错误并使其可供主机客户端程序使用。

  • 客户端错误消息是由 MySQL 客户端库内部生成的,通常涉及与服务器通信的问题。

例如,写入错误日志的服务器端错误消息示例:

  • 在启动过程中产生的此消息提供了状态或进度指示:

    2018-10-28T13:01:32.735983Z 0 [Note] [MY-010303] [Server] Skipping
    generation of SSL certificates as options related to SSL are specified.
    
  • 此消息指示需要 DBA 操作的问题:

    2018-10-02T03:20:39.410387Z 768 [ERROR] [MY-010045] [Server] Event Scheduler:
    [evtuser@localhost][myschema.e_daily] Unknown database 'mydb'
    

例如,发送给客户端程序的服务器端错误消息示例,由mysql客户端显示:

mysql> SELECT * FROM no_such_table;
ERROR 1146 (42S02): Table 'test.no_such_table' doesn't exist

例如,源自客户端库内部的客户端端错误消息示例,由mysql客户端显示:

$> mysql -h no-such-host
ERROR 2005 (HY000): Unknown MySQL server host 'no-such-host' (-2)

无论错误是源自客户端库内部还是从服务器接收的,MySQL 客户端程序可能以不同方式响应。正如刚刚展示的,客户端可以显示错误消息,以便用户采取纠正措施。客户端也可以内部尝试解决或重试失败的操作,或采取其他操作。

错误消息元素

当发生错误时,错误信息包括几个元素:错误代码、SQLSTATE 值和消息字符串。这些元素具有以下特征:

  • 错误代码:此值为数字。它是 MySQL 特有的,不可移植到其他数据库系统。

    每个错误编号都有相应的符号值。例如:

    • 服务器错误编号1146的符号是ER_NO_SUCH_TABLE

    • 客户端错误编号2005的符号是CR_UNKNOWN_HOST

    用于错误消息的错误代码集合被划分为不同的范围;参见 错误代码范围。

    错误代码在给定 MySQL 系列的正式发布(GA)版本中保持稳定。在系列达到 GA 状态之前,新代码仍可能在开发中,并可能会更改。

  • SQLSTATE 值:此值是一个五字符字符串(例如,'42S02')。SQLSTATE 值取自 ANSI SQL 和 ODBC,比数值错误代码更加标准化。SQLSTATE 值的前两个字符表示错误类别:

    • 类别 = '00' 表示成功。

    • 类别 = '01' 表示警告。

    • 类别 = '02' 表示“未找到”。这在游标的上下文中是相关的,并用于控制游标到达数据集末尾时发生的情况。此条件还适用于检索不返回任何行的 SELECT ... INTO *var_list* 语句。

    • 类别 > '02' 表示异常。

    对于服务器端错误,不是所有 MySQL 错误编号都有相应的 SQLSTATE 值。在这些情况下,使用 'HY000'(一般错误)。

    对于客户端错误,SQLSTATE 值始终为 'HY000'(一般错误),因此对于区分一个客户端错误和另一个客户端错误并不具有意义。

  • 消息字符串:此字符串提供了错误的文本描述。

错误代码范围

用于错误消息的错误代码集合被划分为不同的范围,每个范围都有其自己的目的:

  • 1 到 999:全局错误代码。此错误代码范围称为“全局”,因为它是服务器和客户端共享的范围。

    当此范围内的错误源自服务器端时,服务器将其写入错误日志,将错误代码填充为六位数字并添加前缀 MY-

    当此范围内的错误源自客户端时,客户端库将其提供给客户程序,不带零填充或前缀。

  • 1,000 到 1,999:服务器错误代码保留供发送给客户端的消息使用。

  • 2,000 到 2,999:客户端错误代码保留供客户端库使用。

  • 3,000 到 4,999:服务器错误代码保留供发送给客户端的消息使用。

  • 5,000 到 5,999:错误代码保留供 X 插件发送给客户端的消息使用。

  • 10,000 到 49,999:服务器错误代码保留供写入错误日志的消息使用(不发送给客户端)。

    当此范围内的错误发生时,服务器将其写入错误日志,将错误代码填充为六位数字并添加前缀 MY-

  • 50,000 到 51,999:错误代码保留供第三方使用。

服务器处理写入错误日志的错误消息与发送给客户端的错误消息方式不同:

  • 当服务器将消息写入错误日志时,它会在错误代码前面填充零直到六位数,并添加前缀MY-(例如:MY-000022MY-010048)。

  • 当服务器向客户端程序发送消息时,不会在错误代码前面添加零填充或前缀(例如:10363013)。

B.2 错误信息接口

原文:dev.mysql.com/doc/refman/8.0/en/error-interfaces.html

错误消息可能源自服务器端或客户端端,每个错误消息包括错误代码、SQLSTATE 值和消息字符串,如第 B.1 节,“错误消息来源和元素”中所述。有关服务器端、客户端端和全局(服务器和客户端共享)错误的列表,请参阅 MySQL 8.0 错误消息参考。

在程序内部进行错误检查时,请使用错误代码编号或符号,而不是错误消息字符串。消息字符串不经常更改,但有可能。此外,如果数据库管理员更改语言设置,那将影响消息字符串的语言;请参阅第 12.12 节,“设置错误消息语言”。

MySQL 中的错误信息可在服务器错误日志、SQL 级别、客户端程序内部以及命令行中获取。

  • 错误日志

  • SQL 错误消息接口

  • 客户端错误消息接口

  • 命令行错误消息接口

错误日志

在服务器端,一些消息旨在写入错误日志。有关配置服务器写入日志的位置和方式的信息,请参阅第 7.4.2 节,“错误日志”。

其他服务器端错误消息旨在发送给客户端程序,并可按照客户端错误消息接口中描述的方式获取。

特定错误代码所在范围决定服务器是否将错误消息写入错误日志或发送给客户端。有关这些范围的信息,请参阅错误代码范围。

SQL 错误消息接口

在 SQL 级别,MySQL 中有几个错误信息来源:

  • SQL 语句的警告和错误信息可以通过SHOW WARNINGSSHOW ERRORS语句获得。warning_count系统变量表示错误、警告和注释的数量(如果sql_notes系统变量被禁用,则排除注释)。error_count系统变量表示错误的数量。其值不包括警告和注释。

  • GET DIAGNOSTICS语句可用于检查诊断区域中的诊断信息。参见 Section 15.6.7.3, “GET DIAGNOSTICS Statement”。

  • SHOW SLAVE STATUS语句输出包含了关于在复制服务器上发生的复制错误的信息。

  • SHOW ENGINE INNODB STATUS语句输出包含了关于最近的外键错误的信息,如果为InnoDB表的CREATE TABLE语句失败。

客户端错误消息接口

客户端程序从两个来源接收错误:

  • 源自于 MySQL 客户端库内部的客户端端错误。

  • 源自服务器端并由服务器发送给客户端的错误。这些错误在客户端库内接收,从而使它们可供主机客户端程序使用。

特定错误代码所处的范围确定了它是源自客户端库内部还是由客户端从服务器接收。有关这些范围的信息,请参阅错误代码范围。

无论错误是源自客户端库内部还是从服务器接收,MySQL 客户端程序通过调用客户端库中的 C API 函数获得错误代码、SQLSTATE 值、消息字符串和其他相关信息:

  • mysql_errno()返回 MySQL 错误代码。

  • mysql_sqlstate()返回 SQLSTATE 值。

  • mysql_error()返回消息字符串。

  • mysql_stmt_errno()mysql_stmt_sqlstate()mysql_stmt_error()是预处理语句的相应错误函数。

  • mysql_warning_count()返回最近语句的错误、警告和注释数量。

对于客户端库错误函数的描述,请参阅 MySQL 8.0 C API 开发人员指南。

MySQL 客户端程序可能以不同方式响应错误。客户端可能显示错误消息,以便用户采取纠正措施,内部尝试解决或重试失败的操作,或采取其他操作。例如,(使用mysql客户端),连接到服务器失败可能导致此消息:

$> mysql -h no-such-host
ERROR 2005 (HY000): Unknown MySQL server host 'no-such-host' (-2)

命令行错误消息接口

perror程序提供关于错误编号的命令行信息。请参阅 Section 6.8.2, “perror — 显示 MySQL 错误消息信息”。

$> perror 1231
MySQL error code MY-001231 (ER_WRONG_VALUE_FOR_VAR): Variable '%-.64s'
can't be set to the value of '%-.200s'

对于 MySQL NDB Cluster 错误,请使用ndb_perror。请参阅 Section 25.5.16, “ndb_perror — 获取 NDB 错误消息信息”。

$> ndb_perror 323
NDB error code 323: Invalid nodegroup id, nodegroup already existing:
Permanent error: Application error

B.3 问题和常见错误

原文:dev.mysql.com/doc/refman/8.0/en/problems.html

B.3.1 如何确定问题的原因

B.3.2 使用 MySQL 程序时的常见错误

B.3.3 管理相关问题

B.3.4 查询相关问题

B.3.5 优化器相关问题

B.3.6 表定义相关问题

B.3.7 MySQL 中已知的问题

这一部分列出了一些您可能会遇到的常见问题和错误消息。它描述了如何确定问题的原因以及如何解决这些问题。

B.3.1 如何确定问题的原因

译文:dev.mysql.com/doc/refman/8.0/en/what-is-crashing.html

遇到问题时,您应该首先找出是哪个程序或设备导致了问题:

  • 如果出现以下症状之一,则可能是硬件问题(如内存、主板、CPU 或硬盘)或内核问题:

    • 键盘不起作用。通常可以通过按下大写锁定键来检查。如果大写锁定灯不亮,您需要更换键盘。(在执行此操作之前,您应该尝试重新启动计算机并检查键盘的所有电缆。)

    • 鼠标指针不动。

    • 机器不响应远程机器的 ping。

    • 与 MySQL 无关的其他程序表现不正常。

    • 您的系统意外重启。(有问题的用户级程序不应该能够导致系统崩溃。)

    在这种情况下,您应该首先检查所有电缆并运行一些诊断工具来检查您的硬件!您还应该检查是否有任何补丁、更新或服务包可用于您的操作系统,这可能会解决您的问题。还要检查所有库(如 glibc)是否是最新的。

    使用具有 ECC 内存的机器始终是一个好方法,可以早期发现内存问题。

  • 如果键盘被锁定,您可以尝试从另一台机器登录并执行 kbd_mode -a 来恢复。

  • 请检查您的系统日志文件(/var/log/messages 或类似文件)以查找问题的原因。如果您认为问题出在 MySQL 中,您还应该检查 MySQL 的日志文件。请参阅 Section 7.4, “MySQL Server Logs”。

  • 如果您认为没有硬件问题,您应该尝试找出是哪个程序导致了问题。尝试使用 topps、任务管理器或类似程序来查看哪个程序占用了所有 CPU 或锁定了机器。

  • 使用 topdf 或类似程序来检查您是否内存不足、磁盘空间不足、文件描述符不足或其他关键资源不足。

  • 如果问题是某个失控的进程,您可以尝试终止它。如果它不想终止,那么操作系统可能存在 bug。

如果您已经检查了所有其他可能性,并得出结论认为 MySQL 服务器或 MySQL 客户端导致了问题,那么现在是时候创建一个错误报告了,请参阅第 1.5 节“如何报告错误或问题”。在错误报告中,尽量完整地描述系统的行为以及您认为发生了什么。还要说明为什么您认为 MySQL 导致了问题。考虑本章中描述的所有情况。在检查系统时,准确描述任何问题的出现方式。对于程序和日志文件中的任何输出和错误消息,请使用“复制粘贴”方法。

请详细描述哪个程序出现问题以及您看到的所有症状。我们过去收到过许多只声明“系统不工作”的错误报告。这并没有提供任何关于可能出现的问题的信息。

如果一个程序失败,了解以下信息总是有用的:

  • 程序是否出现分段错误(是否转储了核心)?

  • 程序是否占用了所有可用的 CPU 时间?使用top进行检查。让程序运行一段时间,它可能只是在进行计算密集型的评估。

  • 如果mysqld服务器出现问题,您是否可以通过mysqladmin -u root pingmysqladmin -u root processlist得到任何响应?

  • 当您尝试连接到 MySQL 服务器时,客户端程序会有什么提示?(例如尝试使用mysql)客户端是否卡住?程序是否有任何输出?

发送错误报告时,应按照第 1.5 节“如何报告错误或问题”中描述的大纲进行操作。

B.3.2 使用 MySQL 程序时的常见错误

原文:dev.mysql.com/doc/refman/8.0/en/common-errors.html

B.3.2.1 拒绝访问

B.3.2.2 无法连接到 [本地] MySQL 服务器

B.3.2.3 与 MySQL 服务器的连接丢失

B.3.2.4 交互输入密码失败

B.3.2.5 连接过多

B.3.2.6 内存不足

B.3.2.7 MySQL 服务器已断开连接

B.3.2.8 数据包过大

B.3.2.9 通信错误和中止连接

B.3.2.10 表已满

B.3.2.11 无法创建/写入文件

B.3.2.12 命令不同步

B.3.2.13 忽略用户

B.3.2.14 表 ‘tbl_name’ 不存在

B.3.2.15 无法初始化字符集

B.3.2.16 文件未找到及类似错误

B.3.2.17 表损坏问题

这一部分列出了用户在运行 MySQL 程序时经常遇到的一些错误。虽然这些问题出现在尝试运行客户端程序时,但许多问题的解决方案涉及更改 MySQL 服务器的配置。

原文:dev.mysql.com/doc/refman/8.0/en/error-access-denied.html

B.3.2.1 拒绝访问

一个拒绝访问错误可能有很多原因。通常问题与 MySQL 账户有关,服务器允许客户端程序在连接时使用这些账户。参见 Section 8.2, “访问控制和账户管理”,以及 Section 8.2.22, “解决连接到 MySQL 的问题”。

原文:dev.mysql.com/doc/refman/8.0/en/can-not-connect-to-server.html

B.3.2.2 无法连接到 [local] MySQL 服务器

Unix 上的 MySQL 客户端可以通过两种不同的方式连接到 mysqld 服务器:通过使用 Unix 套接字文件连接到文件系统中的文件(默认 /tmp/mysql.sock),或者通过使用 TCP/IP,通过端口号连接。Unix 套接字文件连接比 TCP/IP 更快,但只能在连接到同一台计算机上的服务器时使用。如果不指定主机名或指定特殊主机名 localhost,则使用 Unix 套接字文件。

如果 MySQL 服务器在 Windows 上运行,您可以使用 TCP/IP 进行连接。如果服务器启用了 named_pipe 系统变量,您还可以在运行客户端的主机上使用命名管道进行连接。命名管道的名称默认为 MySQL。如果在连接到 mysqld 时未提供主机名,MySQL 客户端首先尝试连接到命名管道。如果这不起作用,它将连接到 TCP/IP 端口。您可以通过在 Windows 上使用 . 作为主机名来强制使用命名管道。

错误(2002)无法连接到... 通常意味着系统上没有运行 MySQL 服务器,或者在尝试连接到服务器时使用了不正确的 Unix 套接字文件名或 TCP/IP 端口号。您还应检查您正在使用的 TCP/IP 端口是否被防火墙或端口阻止服务阻止。

错误(2003)无法连接到 '*server*' 上的 MySQL 服务器 (10061) 表示网络连接被拒绝。您应检查是否有运行中的 MySQL 服务器,是否已启用网络连接,并且您指定的网络端口是否与服务器上配置的端口一致。

首先检查服务器主机上是否有名为 mysqld 的进程正在运行。(在 Unix 上使用 ps xa | grep mysqld,在 Windows 上使用任务管理器。)如果没有这样的进程,则应启动服务器。请参阅 Section 2.9.2, “Starting the Server”。

如果 mysqld 进程正在运行,您可以尝试以下命令来检查。在您的设置中,端口号或 Unix 套接字文件名可能不同。host_ip 代表运行服务器的机器的 IP 地址。

$> mysqladmin version
$> mysqladmin variables
$> mysqladmin -h `hostname` version variables
$> mysqladmin -h `hostname` --port=3306 version
$> mysqladmin -h host_ip version
$> mysqladmin --protocol=SOCKET --socket=/tmp/mysql.sock version

注意使用反引号而不是前引号与hostname命令一起使用;这会导致hostname的输出(即当前主机名)被替换为mysqladmin命令。如果你没有hostname命令或在 Windows 上运行,你可以手动输入你的机器主机名(不使用反引号)跟在-h选项后面。你也可以尝试使用-h 127.0.0.1来通过 TCP/IP 连接到本地主机。

确保服务器没有配置为忽略网络连接,或者(如果你尝试远程连接)没有配置为仅在其网络接口上本地监听。如果服务器启动时启用了skip_networking系统变量,它根本无法接受 TCP/IP 连接。如果服务器启动时将bind_address系统变量设置为127.0.0.1,它仅在回环接口上本地监听 TCP/IP 连接,不接受远程连接。

检查确保没有防火墙阻止访问 MySQL。你的防火墙可能根据正在执行的应用程序或 MySQL 用于通信的端口号(默认为 3306)进行配置。在 Linux 或 Unix 下,检查你的 IP 表(或类似)配置,确保端口没有被阻止。在 Windows 下,诸如 ZoneAlarm 或 Windows 防火墙等应用程序可能需要配置不要阻止 MySQL 端口。

出现无法连接到本地 MySQL 服务器错误的一些原因如下:

  • mysqld没有在本地主机上运行。检查你的操作系统进程列表,确保mysqld进程存在。

  • 在 Windows 上运行 MySQL 服务器,并有许多 TCP/IP 连接。如果你经常遇到客户端出现这个错误,你可以在这里找到一个解决方法:第 B.3.2.2.1 节,“在 Windows 上连接到 MySQL 服务器失败”。

  • 有人删除了mysqld使用的 Unix 套接字文件(默认为/tmp/mysql.sock)。例如,你可能有一个从/tmp目录中删除旧文件的cron作业。你可以随时运行mysqladmin version来检查mysqladmin正在尝试使用的 Unix 套接字文件是否真的存在。在这种情况下的修复方法是修改cron作业以不删除mysql.sock或将套接字文件放在其他地方。参见第 B.3.3.6 节,“如何保护或更改 MySQL Unix 套接字文件”。

  • 你已经使用--socket=/path/to/socket选项启动了mysqld服务器,但忘记告诉客户端程序新的套接字文件名称。如果你改变了服务器的套接字路径名,你也必须通知 MySQL 客户端。你可以在运行客户端程序时提供相同的--socket选项来做到这一点。你还需要确保客户端有权限访问mysql.sock文件。要找出套接字文件的位置,你可以执行:

    $> netstat -ln | grep mysql
    

    参见第 B.3.3.6 节,“如何保护或更改 MySQL Unix 套接字文件”。

  • 你正在使用 Linux 并且一个服务器线程已经死掉(核心已转储)。在这种情况下,你必须杀死其他mysqld线程(例如,使用kill)才能重新启动 MySQL 服务器。参见第 B.3.3.3 节,“如果 MySQL 一直崩溃怎么办”。

  • 服务器或客户端程序可能没有适当的访问权限来访问保存 Unix 套接字文件或套接字文件本身的目录。在这种情况下,你必须要么更改目录或套接字文件的访问权限,以便服务器和客户端可以访问它们,要么使用指定在服务器可以创建它并且客户端程序可以访问它的目录中的套接字文件名称的--socket选项重新启动mysqld

如果你收到错误消息Can't connect to MySQL server on some_host,你可以尝试以下方法找出问题所在:

  • 通过执行 telnet some_host 3306 并按下回车键几次来检查服务器是否在该主机上运行。(3306 是默认的 MySQL 端口号。如果你的服务器正在监听不同的端口,请更改该值。)如果有一个 MySQL 服务器正在运行并监听该端口,你应该会收到一个包含服务器版本号的响应。如果你收到类似 telnet: Unable to connect to remote host: Connection refused 的错误,则表示给定端口上没有运行服务器。

  • 如果服务器在本地主机上运行,请尝试使用 mysqladmin -h localhost variables 使用 Unix 套接字文件连接。验证服务器配置为监听的 TCP/IP 端口号(它是 port 变量的值)。

  • 如果你在 Linux 下运行,并且启用了安全增强型 Linux(SELinux),请参见 第 8.7 节,“SELinux”。

B.3.2.2.1 连接到 MySQL 服务器在 Windows 上失败

当你在 Windows 上运行一个 MySQL 服务器,并且有许多 TCP/IP 连接到它,而且经常出现你的客户端经常出现 Can't connect to MySQL server 错误时,原因可能是 Windows 不允许足够的短暂(短暂的)端口来服务这些连接。

TIME_WAIT 的目的是在连接关闭后保持接受数据包的连接。这是因为互联网路由可能导致数据包以缓慢的速度到达目的地,可能在双方都同意关闭后到达。如果端口用于新连接,来自旧连接的数据包可能会破坏协议或泄露原始连接的个人信息。TIME_WAIT 延迟通过确保端口在允许延迟数据包到达一段时间后才能被重用,从而防止这种情况发生。

在局域网连接上大大减少 TIME_WAIT 是安全的,因为在这种情况下,包到达的延迟很小,而通过互联网,由于相对较大的距离和延迟,包可能会有很长的延迟。

Windows 允许用户使用短暂(短暂的)TCP 端口。在任何端口关闭后,它将保持在 TIME_WAIT 状态 120 秒。在此时间到期之前,该端口将不再可用。端口号的默认范围取决于 Windows 的版本,旧版本中的端口数量较少:

  • Windows Server 2003 及之前版本:端口范围在 1025–5000

  • Windows Vista、Server 2008 和更新版本:端口范围在 49152–65535

有一个可用 TCP 端口堆栈(5000)和在短时间内打开和关闭大量 TCP 端口以及 TIME_WAIT 状态,你很有可能耗尽端口。解决这个问题有两种方法:

  • 通过调查连接池或尽可能使用持久连接来快速减少消耗的 TCP 端口数量

  • 调整 Windows 注册表中的一些设置(见下文)

重要

以下过程涉及修改 Windows 注册表。在修改注册表之前,请确保备份并确保了解如何在出现问题时恢复它。有关如何备份、恢复和编辑注册表的信息,请查看 Microsoft 知识库中的以下文章:support.microsoft.com/kb/256986/EN-US/

  1. 启动注册表编辑器(Regedt32.exe)。

  2. 在注册表中找到以下键:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
    
  3. 编辑菜单上,单击添加值,然后添加以下注册表值:

    Value Name: MaxUserPort
    Data Type: REG_DWORD
    Value: 65534
    

    这将设置任何用户可用的临时端口数量。有效范围为 5000 到 65534(十进制)。默认值为 0x1388(5000 十进制)。

  4. 编辑菜单上,单击添加值,然后添加以下注册表值:

    Value Name: TcpTimedWaitDelay
    Data Type: REG_DWORD
    Value: 30
    

    这将设置在关闭之前保持 TCP 端口连接处于TIME_WAIT状态的秒数。有效范围为 30 到 300 十进制,尽管您可能希望与微软核实最新允许的值。默认值为 0x78(120 十进制)。

  5. 退出注册表编辑器。

  6. 重新启动计算机。

注意:撤消上述操作应该就像删除您创建的注册表条目一样简单。

原文:dev.mysql.com/doc/refman/8.0/en/error-lost-connection.html

B.3.2.3 与 MySQL 服务器的连接丢失

这个错误消息有三种可能的原因。

通常表示网络连接出现问题,如果经常出现此错误,应检查网络状况。如果错误消息中包含“during query”,那么你可能正在经历这种情况。

有时,“during query”形式发生在数百万行作为一个或多个查询的一部分被发送时。如果你知道正在发生这种情况,你应该尝试将net_read_timeout从默认的 30 秒增加到 60 秒或更长时间,足以完成数据传输。

更少见的情况是,当客户端尝试与服务器进行初始连接时可能会发生这种情况。在这种情况下,如果你的connect_timeout值仅设置为几秒钟,你可以通过将其增加到十秒钟来解决问题,如果你的距离很远或连接速度很慢,可能需要增加更多时间。你可以通过使用SHOW GLOBAL STATUS LIKE 'Aborted_connects'来确定是否遇到了这种不太常见的原因。每次服务器中止初始连接尝试时,该值会增加一次。你可能会看到“reading authorization packet”作为错误消息的一部分;如果是这样,这也表明这是你需要的解决方案。

如果造成这个问题的原因不是上述描述的任何一种,那么你可能遇到了一个与BLOB值大于max_allowed_packet有关的问题,这可能会导致某些客户端出现此错误。有时你可能会看到一个ER_NET_PACKET_TOO_LARGE错误,这证实了你需要增加max_allowed_packet

原文:dev.mysql.com/doc/refman/8.0/en/password-too-long.html

B.3.2.4 交互式输入密码失败

当使用--password-p选项调用 MySQL 客户端程序时,会提示输入密码,但没有后续密码值:

$> mysql -u *user_name* -p
Enter password:

在某些系统上,当在选项文件或命令行中指定密码时可以正常工作,但在交互式输入输入密码:提示时却无法正常工作。这是因为系统提供的用于读取密码的库将密码值限制在少量字符(通常为八个字符)内。这是系统库的问题,而不是 MySQL 的问题。为了解决这个问题,将 MySQL 密码更改为八个或更少字符的值,或将密码放入选项文件中。

原文:dev.mysql.com/doc/refman/8.0/en/too-many-connections.html

B.3.2.5 连接过多

如果客户端在尝试连接到mysqld服务器时遇到连接过多错误,那么所有可用连接都被其他客户端占用。

允许的连接数由max_connections系统变量控制。要支持更多连接,请将max_connections设置为更大的值。

mysqld实际上允许max_connections + 1 个客户端连接。额外的连接是为具有CONNECTION_ADMIN权限(或已弃用的SUPER权限)的帐户保留的。通过授予管理员权限而不是普通用户(不应该需要该权限)的权限,管理员可以连接到服务器并使用SHOW PROCESSLIST来诊断问题,即使最大数量的非特权客户端已连接。请参阅 Section 15.7.7.29, “SHOW PROCESSLIST Statement”。

服务器还允许在专用接口上进行管理连接。有关服务器如何处理客户端连接的更多信息,请参阅 Section 7.1.12.1, “Connection Interfaces”。

原文:dev.mysql.com/doc/refman/8.0/en/out-of-memory.html

B.3.2.6 内存不足

如果你使用mysql客户端程序发出查询,并收到以下错误,意味着mysql没有足够的内存来存储整个查询结果:

mysql: Out of memory at line 42, 'malloc.c'
mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
ERROR 2008: MySQL client ran out of memory

要解决这个问题,首先检查一下你的查询是否正确。返回这么多行是否合理?如果不合理,修改查询然后再试一次。否则,你可以使用带有--quick选项的mysql。这会导致它使用mysql_use_result() C API 函数来检索结果集,这样会减轻客户端的负担(但增加服务器的负担)。

原文:dev.mysql.com/doc/refman/8.0/en/gone-away.html

B.3.2.7 MySQL 服务器已断开连接

本节还涵盖了相关的在查询期间与服务器的连接丢失错误。

MySQL 服务器已断开连接错误最常见的原因是服务器超时并关闭了连接。在这种情况下,通常会收到以下错误代码之一(您收到的错误代码取决于操作系统)。

错误代码描述
CR_SERVER_GONE_ERROR客户端无法向服务器发送问题。
CR_SERVER_LOST客户端在向服务器写入时没有收到错误,但没有得到完整的答案(或任何答案)。

默认情况下,如果没有任何操作发生,服务器在八小时后会关闭连接。您可以通过在启动mysqld时设置wait_timeout变量来更改时间限制。请参见第 7.1.8 节,“服务器系统变量”。

如果您有一个脚本,只需再次发出查询以使客户端进行自动重新连接。这假定您已在客户端启用了自动重新连接(这是mysql命令行客户端的默认设置)。

MySQL 服务器已断开连接错误的一些其他常见原因是:

  • 您(或数据库管理员)已使用KILL语句或mysqladmin kill命令终止了正在运行的线程。

  • 在关闭与服务器的连接后尝试运行查询。这表明应用程序中存在逻辑错误,应该进行更正。

  • 在不同主机上运行的客户端应用程序没有连接到该主机的 MySQL 服务器所需的权限。

  • 您在客户端端从 TCP/IP 连接中获得了超时。如果您一直在使用命令:mysql_options(..., MYSQL_OPT_READ_TIMEOUT,...)mysql_options(..., MYSQL_OPT_WRITE_TIMEOUT,...),则可能会发生这种情况。在这种情况下,增加超时时间可能有助于解决问题。

  • 您在服务器端遇到了超时,并且客户端中的自动重新连接已禁用(MYSQL结构中的reconnect标志等于 0)。

  • 您正在使用 Windows 客户端,而在发出命令之前服务器已经断开连接(可能是因为wait_timeout已过期)。

    在 Windows 上的问题是,在某些情况下,MySQL 在向服务器的 TCP/IP 连接写入时未从操作系统那里收到错误,而是在尝试从连接中读取答案时收到错误。

    解决方法是,如果距上次查询已经很长时间,则在连接上执行mysql_ping()(这是 Connector/ODBC 所做的)或将mysqld服务器上的wait_timeout设置得非常高,以至于实际上永远不会超时。

  • 如果向服务器发送的查询不正确或太大,也可能会出现这些错误。如果mysqld收到一个太大或乱序的数据包,它会假设客户端出现问题并关闭连接。如果需要大型查询(例如,如果您使用大型BLOB列),可以通过设置服务器的max_allowed_packet变量来增加查询限制,其默认值为 64MB。您可能还需要增加客户端端的最大数据包大小。有关设置数据包大小的更多信息,请参阅第 B.3.2.8 节,“数据包过大”。

    插入大量行的INSERTREPLACE语句也可能导致这些错误。这两个语句中的任一个都会向服务器发送一个请求,而不管要插入的行数如何;因此,通过减少每个INSERTREPLACE发送的行数,通常可以避免错误。

  • 如果主机名查找失败(例如,您的服务器或网络依赖的 DNS 服务器崩溃),也可能出现此错误。这是因为 MySQL 依赖主机系统进行名称解析,但无法知道它是否正常工作——从 MySQL 的角度来看,问题与任何其他网络超时问题无法区分。

    如果使用skip_networking系统变量启用 MySQL 启动,则可能还会看到MySQL 服务器已断开连接错误。

    另一个可能导致此错误的网络问题是,如果您的防火墙阻止了 MySQL 端口(默认为 3306),从而完全阻止了与 MySQL 服务器的任何连接。

  • 您还可能遇到这个错误,如果应用程序 fork 子进程,所有这些进程都尝试使用与 MySQL 服务器相同的连接。可以通过为每个子进程使用单独的连接来避免这种情况。

  • 在执行查询时服务器崩溃时,您可能会遇到一个错误。

您可以通过执行mysqladmin version并检查服务器的正常运行时间来检查 MySQL 服务器是否已崩溃并重新启动。如果客户端连接中断是因为mysqld崩溃并重新启动,您应该集中精力找出崩溃原因。首先检查再次发出查询是否再次导致服务器崩溃。请参阅第 B.3.3.3 节,“如果 MySQL 一直崩溃该怎么办”。

您可以通过将log_error_verbosity系统变量设置为 3 来启动mysqld以获取有关丢失连接的更多信息。这会将一些断开连接的消息记录在hostname.err文件中。请参阅第 7.4.2 节,“错误日志”。

如果您想就此问题创建一个错误报告,请确保包含以下信息:

  • 指示 MySQL 服务器是否已崩溃。您可以在服务器错误日志中找到有关此信息的信息。请参阅第 B.3.3.3 节,“如果 MySQL 一直崩溃该怎么办”。

  • 如果特定查询导致mysqld崩溃,并且在运行查询之前已经使用CHECK TABLE检查了涉及的表,您能提供一个可重现的测试案例吗?请参阅第 7.9 节,“调试 MySQL”。

  • MySQL 服务器中wait_timeout系统变量的值是多少?(mysqladmin variables可以为您提供此变量的值。)

  • 您是否尝试启用常规查询日志来运行mysqld,以确定问题查询是否出现在日志中?(参见第 7.4.3 节,“常规查询日志”。)

另请参阅第 B.3.2.9 节,“通信错误和中止连接”和第 1.5 节,“如何报告错误或问题”。

原文:dev.mysql.com/doc/refman/8.0/en/packet-too-large.html

B.3.2.8 Packet Too Large

通信数据包是发送到 MySQL 服务器的单个 SQL 语句,发送到客户端的单个行,或从复制源服务器发送到副本的二进制日志事件。

可以传输到 MySQL 8.0 服务器或客户端的最大可能数据包为 1GB。

当 MySQL 客户端或mysqld服务器接收到大于max_allowed_packet字节的数据包时,会发出ER_NET_PACKET_TOO_LARGE错误并关闭连接。如果通信数据包过大,有些客户端还可能会出现Lost connection to MySQL server during query错误。

客户端和服务器都有自己的max_allowed_packet变量,因此如果要处理大数据包,必须在客户端和服务器中都增加此变量。

如果你正在使用mysql客户端程序,其默认max_allowed_packet变量为 16MB。要设置更大的值,请像这样启动mysql

$> mysql --max_allowed_packet=32M

这将数据包大小设置为 32MB。

服务器的默认max_allowed_packet值为 64MB。如果服务器需要处理大查询(例如,如果您正在使用大BLOB列),可以增加此值。例如,要将变量设置为 128MB,请像这样启动服务器:

$> mysqld --max_allowed_packet=128M

您还可以使用选项文件来设置max_allowed_packet。例如,要为服务器设置为 128MB 的大小,请在选项文件中添加以下行:

[mysqld]
max_allowed_packet=128M

增加此变量的值是安全的,因为只有在需要时才分配额外的内存。例如,mysqld仅在发出长查询或mysqld必须返回大结果行时才分配更多内存。变量的小默认值是为了捕获客户端和服务器之间的不正确数据包,并确保您不会因意外使用大数据包而耗尽内存。

如果您正在使用大型BLOB值,但没有为mysqld分配足够的内存来处理查询,也可能会遇到大数据包的奇怪问题。 如果您怀疑是这种情况,请尝试在mysqld_safe脚本的开头添加ulimit -d 256000,然后重新启动mysqld

原文:dev.mysql.com/doc/refman/8.0/en/communication-errors.html

B.3.2.9 通信错误和中止连接

如果发生连接问题,如通信错误或中止连接,请使用以下信息源诊断问题:

  • 错误日志。参见 Section 7.4.2, “The Error Log”。

  • 一般查询日志。参见 Section 7.4.3, “The General Query Log”。

  • Aborted_*xxx*Connection_errors_*xxx*状态变量。参见 Section 7.1.10, “Server Status Variables”。

  • 主机缓存,可通过性能模式host_cache表访问。参见 Section 7.1.12.3, “DNS Lookups and the Host Cache”,以及 Section 29.12.21.3, “The host_cache Table”。

如果log_error_verbosity系统变量设置为 3,您可能会在错误日志中找到类似以下消息:

[Note] Aborted connection 854 to db: 'employees' user: 'josh'

如果客户端甚至无法连接,服务器会增加Aborted_connects状态变量。连接尝试失败可能出现以下原因:

  • 客户端尝试访问数据库但没有权限。

  • 客户端使用了错误的密码。

  • 连接数据包不包含正确的信息。

  • 超过connect_timeout秒才能获取连接数据包。参见 Section 7.1.8, “Server System Variables”。

如果发生这些情况,可能表明有人试图入侵您的服务器!如果启用了一般查询日志,这些类型的问题的消息将记录在其中。

如果客户端成功连接但后来断开连接不当或被终止,服务器会增加Aborted_clients状态变量,并在错误日志中记录一个中止连接的消息。可能的原因有以下几种:

  • 客户端程序在退出之前没有调用mysql_close()

  • 客户端在超过wait_timeoutinteractive_timeout秒的时间内没有向服务器发出任何请求而处于休眠状态。参见 Section 7.1.8, “Server System Variables”。

  • 客户端程序在数据传输过程中突然结束。

其他导致连接中断或客户端中断的问题原因:

  • max_allowed_packet 变量值过小,或查询需要的内存超过为 mysqld 分配的内存。参见 Section B.3.2.8, “Packet Too Large”。

  • 在 Linux 上使用以太网协议,包括半双工和全双工。一些 Linux 以太网驱动程序存在此 bug。您可以通过在客户端和服务器机器之间使用 FTP 传输大文件来测试此 bug。如果传输以突发-暂停-突发-暂停的模式进行,那么您遇到了 Linux 双工综合症。将网络卡和集线器/交换机的双工模式切换为全双工或半双工,并测试结果以确定最佳设置。

  • 导致读取中断的线程库问题。

  • TCP/IP 配置不当。

  • 故障的以太网、集线器、交换机、电缆等。只有通过更换硬件才能正确诊断此问题。

参见 Section B.3.2.7, “MySQL server has gone away”。

原文:dev.mysql.com/doc/refman/8.0/en/full-table.html

B.3.2.10 表已满

如果出现表满错误,可能是磁盘已满或表已达到其最大大小。MySQL 数据库的有效最大表大小通常由操作系统对文件大小的限制确定,而不是由 MySQL 内部限制确定。参见 第 10.4.6 节,“表大小限制”。

原文:dev.mysql.com/doc/refman/8.0/en/cannot-create.html

B.3.2.11 无法创建/写入文件

如果对某些查询出现以下类型的错误,意味着 MySQL 无法在临时目录中为结果集创建临时文件:

Can't create/write to file '\\sqla3fe_0.ism'.

上述错误是 Windows 的典型消息;Unix 的消息类似。

一种解决方法是使用 --tmpdir 选项启动 mysqld,或将该选项添加到选项文件的 [mysqld] 部分。例如,要指定目录为 C:\temp,请使用以下行:

[mysqld]
tmpdir=C:/temp

C:\temp 目录必须存在并具有足够的空间供 MySQL 服务器写入。参见 Section 6.2.2.2, “使用选项文件”。

这个错误的另一个原因可能是权限问题。确保 MySQL 服务器可以写入 tmpdir 目录。

还要检查使用 perror 得到的错误代码。服务器无法写入表的一个原因是文件系统已满:

$> perror 28
OS error code  28:  No space left on device

如果在启动过程中出现以下类型的错误,表明用于存储数据文件的文件系统或目录受到写保护。只要写错误是针对测试文件的,那么这个错误并不严重,可以安全地忽略。

Can't create test file /usr/local/mysql/data/master.lower-test

原文:dev.mysql.com/doc/refman/8.0/en/commands-out-of-sync.html

B.3.2.12 命令不同步

如果在客户端代码中出现Commands out of sync; you can't run this command now,说明你在错误的顺序中调用客户端函数。

这可能发生在你使用mysql_use_result()并在调用mysql_free_result()之前尝试执行新查询时。也可能发生在你尝试执行两个返回数据的查询而没有在中间调用mysql_use_result()mysql_store_result()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值