编者按
为方便大家对MySQL 5.7的认识和学习,社群众译者倾力翻译了MySQL 5.7 FAQ文档,以解答大家在使用过程中的各种困惑。
由于篇幅过大,本文将摘录部分精华,需要完整版的同学请务必点击文末的链接或回复“FAQ”到DBAplus社群订阅号下载珍藏~
文中部分内容涉及MySQL 5.7官方用户手册(以下简称“手册”),建议在阅读本文同时,登陆:https://dev.mysql.com/doc/refman/5.7/en/ 配合参考食用,效果更佳~而下载了完整版的同学则可直接点击超链接跳转至相应页面查看。
MySQL 5.7 FAQ目录一览
一、一般问题
二、存储引擎
三、SQL服务器模式
四、存储过程与函数
五、触发器
六、视图
七、INFORMATION_SCHEMA
八、Migration迁移
九、Security安全
十、MySQL Cluster
十一、中文、日文和朝鲜语字符集
十二、连接器和APIs
十三、复制
十四、MySQL企业线程池
十五、InnoDB变更缓冲区
十六、InnoDB表空间加密
十七、虚拟化支持
共计188个问答
精华摘录
Part 1 MySQL Cluster
1、哪个版本的MySQL软件支持NDB Cluster?我是否不得不使用源码编译?
在标准的MySQL Server5.7版本中NDB Cluster是不支持的。然而,MySQL NDB Cluster是作为一个单独的产品来提供。目前,生产环境以下NDB Cluster版本序列可用:
-
NDB Cluster 7.2. 这个序列是NDB Cluster之前的一个通用版本,尽管我们推荐新部署采用NDB Cluster7.5的版本,目前来说,还是可以用于生产。最近的NDB Cluster 7.2版本可从http://dev.mysql.com/downloads/cluster/获得。
-
NDB Cluster 7.3. 这个序列是NDB Cluster之前的一个通用版本,尽管我们推荐新部署采用NDB Cluster7.5的版本,目前来说,还是可以用于生产。最近的NDB Cluster 7.3版本可以从http://dev.mysql.com/downloads/cluster/获得。
-
NDB Cluster 7.4. 这个序列是NDB Cluster最新的通用版本,它是基于NDB 7.4版本的存储引擎和MySQL5.6,尽管我们推荐新部署采用NDB Cluster7.5的版本,目前来说,还是可以用于生产。最近的NDB Cluster 7.4版本可以从http://dev.mysql.com/downloads/cluster/获得。
-
NDB Cluster 7.5. 这个序列是NDB Cluster最新的通用版本,它是基于NDB 7.5版本的存储引擎和MySQL5.7. NDB Cluster 7.5可用作生产。在这个序列中,生产新部署建议采用NDB Cluster7.5的版本。当前的版本是NDB Cluster7.5.5。最近的NDB Cluster 7.5版本可以从http://dev.mysql.com/downloads/cluster/获得。
任何新环境的部署,你应该使用NDB Cluster 7.5。如果你使用的是NDB Cluster的老版本,你应该尽可能快地升级到这个版本。(为了对NDB Cluster 7.5中的一些改进有大致了解,请看手册21.1.4节“MySQL NDB Cluster7.5有什么新功能”)
你可以使用以下命令来检查你的MySQL Server是否支持NDB:
SHOW VARIABLES LIKE 'have_%', SHOW ENGINES, 或SHOW PLUGINS。
2、我需要什么特殊的网络来运行NDB Cluster吗?集群中的计算机如何通讯?
NDB集群的目的是用于在高带宽环境中,计算机使用TCP / IP连接。其性能直接取决于集群计算机之间的连接速度。NDB集群最小连接要求包括典型的100Mb以太网网络或相当的网络。只要可用,我们建议你使用千兆以太网。
3、为了运行NDB Cluster我需要多少计算机,为什么?
一个可行的集群至少需要3台计算机。然而,一个NDB Cluster推荐的最小计算机数是4:管理节点和SQL节点各需要一个节点,另外两台计算机用作数据节点。设计两个数据节点的目的是为了提供冗余。管理节点必须运行在一个独立的机器上,万一某个数据节点故障,可以保证提供持续的仲裁服务。
为了提高吞吐量和高可用性,你应该使用多个SQL节点(连接到集群的MySQL服务器)。运行多个管理服务器也是可能的(虽然不是严格必要的)。
4、使用NDB Cluster需要多少RAM?完全使用磁盘内存是否可行?
以前NDB集群只是运行在内存中。MySQL 5.1和以后还提供将NDB集群存储在磁盘上的能力。(注意,我们没有计划将这种能力移植到以前版本)参见手册21.5.13节“NDB集群磁盘数据表”,以获取更多信息。
对于内存中的NDB表,你可以使用以下公式计算集群中的每个数据节点大致需要的内存的估计值:
(SizeofDatabase × NumberOfReplicas × 1.1 ) / NumberOfDataNodes
计算更准确的内存需求需要有些限定条件,对于集群数据库中的每个表,每一行所需的存储空间(详情参见手册12.8节,“数据类型存储需求”)乘以行数。就像以下列出的,你也必须记住计算任何列索引的内存占用:
-
NDB Cluster表上创建每个主键或哈希索引需要21-25字节/记录。这些索引使用IndexMemory。
-
每个排序的索引需要10字节/记录,占用的是DataMemory。
-
创建的主键或唯一索引会同时创建一个排序的索引,除非创建索引时指定使用HASH。换句话说:
1)集群表的主键或唯一索引通常每条记录占用31到35个字节。
2)然而,如果使用HASH来创建主键或唯一索引,那么每条记录只需要21到25个字节。
在NDB Cluster表创建过程中,对于所有的主键和唯一索引,通常使用HASH的方式比不使用HASH的方式会让更新会快很多,在一些情况下,甚至会快20%到30%。这是因为需要更少的内存(因为不会创建排序的索引),同时使用的CPU也更少(因为需要读和可能更新的索引更少)。然而,这也意味着使用范围扫描的查询需要通过其它方式来满足,否则会导致选择变慢。
当计算集群内存需求, 在最近的MySQL 5.7版本,您可能会发现一个叫ndb_size.pl的工具可用。这个Perl脚本连接到当前的(非集群)MySQL数据库,并创建一个关于“如果使用NDBCLUSTER存储引擎,这个数据库需要多少空间”的报告。有关更多信息,请参见手册21.4.25节,“ndb_size.pl - NDBCLUSTER大小需求估计量”。
尤为重要的是,要记住,每一个NDB集群表必须有一个主键。如果一个都没有定义,NDB存储引擎会自动创建一个主键,并且这个自动创建的主键不使用HASH。
在特定的时间,通过使用ndb_mgm客户端的REPORT MEMORYUSAGE命令,您可以确定有多少内存被用于存储NDB集群数据和索引,参见手册21.5.2 “NDB集群管理客户端命令”以获取更多信息。此外,当DataMemory或IndexMemory使用的内存达到80%,就会有警告写到集群日志,同样,当使用达到85%,90%等就会再次写入告警日志。
5、我能在虚拟机(比如通过VMWare、Parallels或 Xen创建的虚拟机)运行NDB Cluster节点吗?
从NDB Cluster 7.2开始,NDB Cluster就支持使用虚拟机。我们目前支持和测试使用Oracle VM。
一些NDB集群用户已经成功使用其它虚拟化产品部署NDB集群;在这种情况下,Oracle可以提供NDB集群支持,但特定于虚拟环境问题必须提到产品的供应商。
6、我尝试迁移到一个NDB Cluster数据库。装载过程过早结束并且我收到了如下错误信息:ERROR 1114: The table 'my_cluster_table' is full,为什么会发生?
原因很可能是你的设置并没有为所有表数据和索引提供足够的RAM,包括NDB存储引擎所需的主键,以及为可能存在的表定义中不包括主键的表自动创建的主键。
同样值得注意的是,所有数据节点应该有相同数量的内存,因为对于任何数据节点而言,集群中没有数据节点可以使用比最少可用内存更多的内存。例如,如果有四台电脑作为集群数据节点,三个有3 GB内存可用来存储集群数据,而另外一个数据节点只有1 GB内存,然后每个数据节点可以投入最多1 GB用于 NDB集群数据和索引。
在某些情况下,即使ndb_mgm -e "ALL REPORT MEMORYUSAGE"显示有大量空闲的DataMemory,MySQL客户端应用程序中可能返回 “Table is full”的错误。你可以强制NDB为NDB集群表创建额外的分区,因此,对于使用MAX_ROWS选项创建的表的哈希索引就有更多的内存可用。一般来说,设置MAX_ROWS为你希望存储表中行数的两倍应该就够了。
出于类似原因,有时你也可能遇到数据负载很高的数据节点的重启问题。在NDB集群7.1及以后,增加的MinFreePct参数通过保留一定比例(默认5%)的DataMemory和IndexMemory来帮助解决重启过程中的问题。这个保留内存不用于存储NDB表或数据。
7、我怎样导入一个已经存在的MySQL数据库到一个NDB Cluster?
你可以像任何其它版本的MySQL一样导入数据库到NDB Cluster。除了在这个FAQ提到的限制外,唯一的特殊要求是包含在集群中的表必须是NDB存储引擎。这意味着创建这些表必须使用ENGINE=NDB或ENGINE=NDBCLUSTER。
通过使用一个或多个ALTER TABLE语句,也可以将现有使用其它存储引擎的表转换成NDBCLUSTER存储引擎。然而,在进行转换之前,表的定义必须兼容NDBCLUSTER存储引擎。在MySQL 5.7中,也需要一个额外的方法,参见手册21.1.6“NDB集群的已知的限制”获取详细信息。
8、NDB Cluster支持IPV6吗?
SQL节点(MySQL服务器)之间的连接是支持IPv6的,但是其它类型的NDB Cluster节点之间的连接必须使用IPv4。
实际上,这意味着你可以在NDB Cluster之间的复制使用IPv6,但是同一个NDB Cluster中节点的连接必须使用IPv4。更多信息,参见手册21.6.3“NDB集群复制已知的问题”。
9、在一个有多个MySQL服务器的NDB Cluster中怎样管理MySQL的用户?
MySQL用户账号和权限通常不会在访问同一个集群的不同MySQL服务器之间自动传播。MySQL NDB Cluster 7.2及以后版本提供分布式的权限支持。然而权限分发并不会自动启用,你可以依据MySQL NDB Cluster文档提供的过程来激活这个功能。参见手册21.5.15节“NDB Cluster的分布式MySQL权限”。
10、我怎样备份和还原NDB Cluster?
你可以在NDB管理的客户端和ndb_restore程序中使用NDB Cluster原生的备份和恢复功能。详见手册21.5.3“在线备份NDB Cluster”和“ndb_restore-还原一个NDB Cluster备份”。
你也可以使用mysqldump和MySQL Server为备份恢复提供的传统功能。更多信息请见手册5.5.4“mysqldump-数据库的备份程序”。
Part 2 存储过程与函数
1、MySQL 5.7支持存储过程和函数吗?
是的。MySQL 5.7支持两种类型的存储例程:存储过程和存储函数。
2、有没有关于MySQL存储过程的论坛?
有。参见http://forums.mysql.com/list.php?98
3、一个给定数据库中,有办法查询所有的存储过程和存储函数吗?
有的。比如给定的数据库名为dbname,可以对INFORMATION_SCHEMA.ROUTINES 表上进行如下查询:
SELECT ROUTINE_TYPE, ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA='dbname';
更多信息,参见手册24.20节“INFORMATION_SCHEMA ROUTINES 表”。
对于存储例程内包体的查询,可通过SHOW CREATE FUNCTION(对于存储函数)和 SHOW CREATE PROCEDURE(对于存储例程)语句来查询。更多信息,参见手册14.7.5.9节“查询存储过程定义”。
4、一个存储过程能否访问表?
可以。一个存储过程可根据需要来对一张或多个表进行访问。
5、能从MySQL 5.7的存储例程中返回结果集吗?
存储过程可以,但存储函数不可以。如果你在存储过程中进行一般性查询,其结果集会直接返回到客户端。为此,你需要使用比MySQL 4.1或更高版本的客户端/服务器端。这意味着需要使用MySQLi的扩展而不是旧的MySQL的扩展,比如在PHP程序中。
6、在复制时,存储过程或函数的功能如何被执行?
MySQL会记录存储过程中的每个DML事件,并将其分解动作同步到备服务器中。存储过程的具体调用执行将不会被同步。
存储函数对数据的更改只记录为函数调用,而不记录其带来的操作事件。
7、有特殊安全需求的存储过程或函数如何被复制?
是的。因为从属服务器有权执行任何从主服务器读取的二进制日志,包括被复制的有特殊安全约束的存储函数。如果复制或二进制日志(为了基于时间点的恢复)记录是正常的,DBA可以用两种方式安全打开:
-
任何用户想创建存储函数必须被授予超级特权。
-
另外,DBA可以log_bin_trust_function_creators系统变量设置为1,这使得任何标准创建常规特权来创建存储功能。
8、对复制存储过程和函数的行为有什么限制吗?
不确定性(随机)或存储过程中基于时间的行为会导致不能正确地被复制。嵌入在存储过程也可能不正确地复制。从本质上讲,随机产生的结果是无法预测、无法完全复制的。因此,同步到从库的随机动作可能和主库不一致。声明存储函数为DETERMINISTIC或将系统变量log_bin_trust_function_creators设置为0将不允许random-valued操作调用。
此外,基于时间的行动不能复制到从数据库上,因为这样的行为在一个存储过程的时机并不是通过复制使用的二进制日志来再生的。它只记录DML事件和没有时间限制的因素。
最后, 对于nontransactional表,因较多DML操作(如批量插入)发生的错误,可能会引起复制问题,这些问题会导致主库中部分完成的变动在从数据库中不会做任何变动。DML的功能模块可对主库中引起错误的动作中加上IGNORE,这样同步到从数据库中的动作,将会被忽略且不会引起错误。
9、上述的限制是否影响MySQL基于时间点的恢复功能?
对复制的影响与基于时间点恢复的影响相同。
10、如何弥补上述的局限性?
你可以选择基于语句级的复制或基于行级的复制。先前复制的实现依赖基于语句级的二进制日志。基于行的二进制日志可解决前面提到的局限性。
可以使用复制的混合模式(通过--binlog-format=mixed启动服务)。通过这种混合,复制模式能智能地选择是基于语句级的复制安全可用,还是基于行级的复制更适合。
更多信息,参见手册18.2.1节“复制格式”。
Part 3 复制
1、备库是否必须一直连接到主库?
不是。备库可以关掉或断开几小时甚至几天,然后重新连接上并补上更新。例如,您可以通过拨号连接设置一个主/从关系,拨号连接只是偶尔的和短时间的在线。这意味着,在任何给定的时间,备库并不保证与主库保持同步,除非你采取一些特殊的措施。
为了确保已经断开连接的备库可以继续追赶(主库),您不能从主库删除包含尚未复制到备库信息的二进制日志文件。异步复制只有在备库能够继续从上次读取事件的点继续阅读二进制日志才能工作。
2、为了启用复制,我是否必须在主库和备库启用网络?
是的,必须在主库和备库上启用网络。如果没有启用网络,备库不能连接到主库和传输二进制日志。检查主备服务器的配置文件都没有启用skip-networking选项。
3、设置双向复制时,我应该注意哪些问题?
MySQL复制当前不支持任何保证在主备库之间的分布式更新(跨服务器)的原子性的锁定协议。换句话说,客户端A对co-master 1进行更新,与此同时,在这个更新传播到co-master2之前,客户端B可以对co-master 2进行一个更新,这个(客户端B的更新操作)使得客户端A对co-master2的作用和对co-master1的作用存在变得不同的可能。
因此,当客户端A对co-master2进行更新操作,即使来自co-master2的所有的更新都已经被传播,它会产生与co-master1上不同的表。这意味着在一个双向复制关系中,你不应该链接两个服务器,除非你确信你的更新可以以任何顺序发生并安全地执行,或者除非你在客户端代码以某种方法注意避免次序混乱的更新。
你也应该意识到双向复制,考虑到更新实际上并不会提高很多性能(如果有的话)。就像只有一台服务器那样,每个服务器必须做相同数量的更新。唯一的区别,就是少一点锁争用,因为另一个服务器上更新,在一个slave线程中是串行的,甚至这个好处可能会被网络延迟所抵消。
4、我如何使用复制来提高系统的性能?
设置一个主服务器,然后将所有的写直接指向它。然后配置你的预算和机架空间允许的备库,然后在主备库之间分配读请求。你也可以在备端使用--skip-innodb, --low-priority-updates和--delay-key-write=ALL选项来启动备库,从而获得速度的提升。在这种情况下,备库会使用非事务的MyISAM表替代InnoDB表来消除事务的开销从而获得更好的速度。
5、如何使用复制来提供冗余或高可用?
如何实现冗余是完全依赖于您的应用程序和环境。高可用性解决方案(用自动故障转移)需要主动监测和自定义脚本或第三方工具提供从原来的MySQL服务器到备库的故障转移支持。
为了手工处理这个过程,您可以从失败的主库转换到一个预先配置的备库,可以通过改变应用程序跟新服务器交谈,或通过调整MySQL服务器的DNS,从失败的服务器到新服务器来实现。
更多信息和一些示例解决方案,请见手册18.3.7节“故障切换过程中的主库切换”。
Part 4 中文、日文和朝鲜语字符集
这组常见问题来源于MySQL的支持和开发团队在处理许多询问CJK(中文-日文-朝鲜语)相关问题的经验。这里只做简单呈现,具体请下载完整版阅读。
1、从哪里可以找到MySQL手册的汉语,日语,和朝鲜语的翻译?
MySQL 5.6日文的手册可以从这里下载: http://dev.mysql.com/doc/.
2、从哪里可以获得MySQL关于CJK和相关的问题的帮助?
下面这些资源可用:
从https://wikis.oracle.com/display/mysql/List+of+MySQL+User+Groups可以找到MySQL用户组的列表。
与字符集相关问题的特性请求,请看http://tinyurl.com/y6xcuf。
访问MySQL字符集、排序、Unicode论坛。外语相关论坛,也可以访问http://forums.mysql.com/.
Part 5 触发器
1、MySQL 5.7支持语句级或行级的触发器吗?
是的。在MySQL 5.7中,触发器是针对行级的。即触发器在对插入、更新、删除的行级操作时被触发。但是,MySQL 5.7不支持FOR EACH STATEMENT。
2、一张表可以同时具有相同触发事件和动作时间的多个触发器吗?
MySQL 5.7.2,对于一个给定的表有相同的触发事件和动作时间,可以定义多个触发器。例如,你可以为一张表创建两个BEFORE UPDATE触发器。默认情况下,有相同触发事件和动作时间的触发器会按被创建的顺序所激活。对于相同触发事件和动作时间的触发器,可以在FOR EACH ROW后标注FOLLOWS 或 PRECEDES来影响触发器的执行顺序。使用FOLLOWS,新触发器在已有触发器之后激活。使用PRECEDES,新触发器在已有触发器之前激活。
3、触发器能和复制模块一起使用吗?
可以。但是,复制的工作方式取决于使用的是MySQL各版本中均有的基于语句级传统格式,还是MySQL 5.1中引入的基于行的复制格式。
当使用基于语句级的复制格式时,主库中执行的语句将会同步到从数据库中按语句执行。
当使用基于行级的复制,主数据库中触发器执行的语句会同步到到从数据库,但不会在从数据库上执行,而是将主库中触发器执行的改变同步到从数据库中。有关更多信息,请参见手册18.4.1.35节”复制和触发器“。
4、触发器在主库中触发的动作如何被同步到从数据库?
同样,这取决于是使用基于语句还是基于行级的复制。
基于语句的复制:
首先,在主库中存在的触发器将会在从数据库重新创建。一旦完成,复制将其作为标准的DML语句参于复制工作。比如,主库中的emp表,拥有AFTER插入操作的触发器。相用的表和触发器也会存在于从数据库中。复制的流程如下:
-
创建对EMP表的插入语句;
-
激活EMP表的AFTER触发器;
-
插入语句写入二进制日志;
-
复制进程会选出EMP表的插入语句并在从数据库上执行;
-
从数据库上将会存在AFTER触发器并激活。
基于行的复制:
当使用基于行的复制时,主库上执行触发器带来的变动将会应用在从数据库上。但在使用基于行的复制时,触发器并不真的在从数据库上执行。这是因为,如果在主从数据库都执行的同时,从数据库再次应用了主库上触发器执行带来的变动,将会在从数据库上应用两次,导致主从数据库上数据不一致。
大数据情况下,基于语句的复制和基于行的复制结果是相同的。但当主从数据库上的触发器不同时,将不能使用基于行的复制格式。(这是因为基于行级的复制,主库上触发器执行同步到从数据库上的是数据改变,而不是语句执行,并且相应的触发器也不会在从数据库上执行。)不同的是,在使用基于语句的复制时,触发器执行的任何语句都将会被应用。
更多信息,请参见手册18.4.1.35节“复制和触发器”。
Part 6 InnoDB表空间加密
1、数据会被解密给被授权可以查看它的用户吗?
是的。InnoDB表空间加密是用来为客户提供能够在数据库中透明地应用加密而不会影响现有应用程序。返回加密格式的数据将破坏大多数现有的应用程序。InnoDB表空间加密提供了加密的同时消除了传统数据库加密的解决方案中相应的开销,通常这些开销需要对应用程序,数据库触发器和视图进行成本很高的和大量的修改。
2、InnoDB表空间加密使用的是什么加密算法?
InnoDB表空间加密支持高级加密标准(AES356)的基于块的加密算法。对于表空间密钥的加密,它使用的是电子码(ECB)块加密模式,对于数据加密,它使用的是密码块链接(CBC)加密模式。
3、是否可以使用第三方提供的加密算法来替代InnoDB表空间加密特性提供的加密算法?
不能,不可以使用其它的加密算法。所提供的加密算法被广泛地接受。
4、InnoDB表空间加密支持什么数据类型和数据长度?
InnoDB表空间加密支持所有的数据类型,没有数据长度限制。
5、InnoDB表空间加密与MySQL已经提供的加密函数有何不同?
MySQL有对称和非对称加密APIs可以用来手动加密数据库中的数据。然而,应用程序必须通过调用API函数管理加密密钥和执行所需的加密及解密操作。
InnoDB表空间加密不需要应用程序修改,对最终用户是透明的,并提供自动化、内置密钥管理功能。
原文发布时间为:2017-03-13
本文来自云栖社区合作伙伴DBAplus