首页 文章 精选 留言 我的

精选列表

搜索[漏洞评估],共10002篇文章
优秀的个人博客,低调大师

MySQL VARCHAR 最佳长度评估实践

你的 VARCHAR 长度合适么? 作者:官永强,爱可生 DBA 团队成员,擅长 MySQL 运维方面的技能。热爱学习新知识,亦是个爱打游戏的宅男。 作者:李富强,爱可生 DBA 团队成员,熟悉 MySQL,TiDB,OceanBase 等数据库。相信持续把对的事情做好一点,会有不一样的收获。 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 本文约 2200 字,预计阅读需要 8 分钟。 背景描述 有客户反馈,他们对一个 VARCHAR 类型的字段进行长度扩容。第一次可以很快就可以修改好,但是第二次却需要执行很久。比较疑惑明明表中的数据量是差不多的,为什么从 VARCHAR(20) 调整为 VARCHAR(50) 就比较快,但是从 VARCHAR(50) 调整为 VARCHAR(100) 就需要执行很久呢? 于是我们对该情况进行场景复现并进行问题分析。 环境信息 本次验证涉及到的产品及版本信息如下: 产品 版本 MySQL 5.7.25-log MySQL Community Server (GPL) Sysbench sysbench 1.0.17 场景复现 3.1 数据准备 mysql> show create table test.sbtest1; +---------+----------------------------------------+ | Table | Create Table | +---------+----------------------------------------+ | sbtest1 | CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` varchar(20) COLLATE utf8mb4_bin NOT NULL DEFAULT '', `pad` varchar(20) COLLATE utf8mb4_bin NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin | +---------+----------------------------------------+ 1 row in set (0.00 sec) mysql> select count(*) from test.sbtest1; +----------+ | count(*) | +----------+ | 1000000 | +----------+ 1 row in set (0.10 sec) 3.2 问题验证 模拟客户的描述,我们对字段 c 进行修改,将 VARCHAR(20) 修改为 VARCHAR(50) 后再修改为 VARCHAR(100),并观察其执行所需时间,以下是相关的操作命令以及执行结果: mysql> ALTER TABLE test.sbtest1 MODIFY c VARCHAR(50); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show create table test.sbtest1; +---------+-------------------------------+ | Table | Create Table | +---------+-------------------------------+ | sbtest1 | CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL, `pad` varchar(20) COLLATE utf8mb4_bin NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin | +---------+--------------------------------------------------------+ 1 row in set (0.00 sec) mysql> ALTER TABLE test.sbtest1 MODIFY c VARCHAR(100); Query OK, 1000000 rows affected (4.80 sec) Records: 1000000 Duplicates: 0 Warnings: 0 mysql> show create table test.sbtest1; +---------+---------------------------+ | Table | Create Table | +---------+---------------------------+ | sbtest1 | CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL, `pad` varchar(20) COLLATE utf8mb4_bin NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin | +---------+------------------------------------------------------------------------+ 1 row in set (0.00 sec) 通过验证发现,该问题会稳定复现,故继续尝试去修改,最终发现在修改 VARCHAR(63) 为 VARCHAR(64) 时需要执行很久,但在 64 之后继续进行长度扩容发现可以很快完成。 mysql> ALTER TABLE test.sbtest1 MODIFY c VARCHAR(63); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> ALTER TABLE test.sbtest1 MODIFY c VARCHAR(64); Query OK, 1000000 rows affected (4.87 sec) Records: 1000000 Duplicates: 0 Warnings: 0 mysql> show create table test.sbtest1; +---------+---------------+ | Table | Create Table | +---------+---------------+ | sbtest1 | CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL, `pad` varchar(20) COLLATE utf8mb4_bin NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin | +---------+------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> ALTER TABLE test.sbtest1 MODIFY c VARCHAR(65); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> ALTER TABLE test.sbtest1 MODIFY c VARCHAR(66); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 3.3 问题分析 对于 VARCHAR(63) 修改为 VARCHAR(64) 需要执行很久的这个情况进行分析。通过查阅官方文档 发现,由于 VARCHAR 字符类型在字节长度为 1 时可存储的字符为 0~255。当前字符集类型为 UTF8MB4,由于 UTF8MB4 为四字节编码字符集,即一个字节长度可存储 63.75(255/4)个字符,所以当我们将 VARCHAR(63) 修改为 VARCHAR(64) 时,需要增加一个字节去进行数据的存储,就要通过建立临时表的方式去完成本次长度扩容,故需要花费大量时间。 拓展验证 4.1 数据准备 mysql> show create table test_utf8.sbtest1; +---------+----------------------------------------+ | Table | Create Table | +---------+----------------------------------------+ | sbtest1 | CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` varchar(20) NOT NULL DEFAULT '', `pad` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8 | +---------+------------------+ 1 row in set (0.00 sec) mysql> select count(*) from test_utf8.sbtest1; +----------+ | count(*) | +----------+ | 1000000 | +----------+ 1 row in set (0.10 sec) 4.2 UTF8 场景验证 由于 UTF8 为三字节编码字符集,即一个字节可存储 85(255/3=85)个字符。 本次修改顺序:VARCHAR(20)→VARCHAR(50)→VARCHAR(85),并观察其执行所需时间,以下是相关的操作命令以及执行结果: mysql> ALTER TABLE test_utf8.sbtest1 MODIFY c VARCHAR(50) ,algorithm=inplace,lock=none; Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> ALTER TABLE test_utf8.sbtest1 MODIFY c VARCHAR(85) ,algorithm=inplace,lock=none; Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show create table test_utf8.sbtest1; +---------+-------------------------------+ | Table | Create Table | +---------+-------------------------------+ | sbtest1 | CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` varchar(85) DEFAULT NULL, `pad` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8 | +---------+--------------------------------------------------+ 1 row in set (0.00 sec) 修改顺序:VARCHAR(85)→VARCHAR(86)→VARCHAR(100),此时我们会观察到执行的 SQL 语句直接返回报错。于是我们删除 algorithm=inplace ,lock=none 这两个参数,即允许本次 SQL 创建临时表以及给目标表上锁,然后重新执行 SQL,以下是相关的操作命令以及执行结果: mysql> ALTER TABLE test_utf8.sbtest1 MODIFY c VARCHAR(86) ,algorithm=inplace,lock=none; ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY. mysql> ALTER TABLE test_utf8.sbtest1 MODIFY c VARCHAR(86); Query OK, 1000000 rows affected (4.94 sec) Records: 1000000 Duplicates: 0 Warnings: 0 mysql> show create table test_utf8.sbtest1; +---------+-------------------------------+ | Table | Create Table | +---------+-------------------------------+ | sbtest1 | CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` varchar(86) DEFAULT NULL, `pad` varchar(20) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8 | +---------+--------------------------------------------------+ 1 row in set (0.00 sec) mysql> ALTER TABLE test_utf8.sbtest1 MODIFY c VARCHAR(100) ,algorithm=inplace,lock=none; Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 4.3 UTF8MB4 场景验证 由于 UTF8MB4 为四字节编码字符集,即一个字节长度可存储 63(255/4=63.75)个字符。 本次修改顺序:VARCHAR(20)→VARCHAR(50)→VARCHAR(63),并观察其执行所需时间,以下是相关的操作命令以及执行结果: mysql> ALTER TABLE test.sbtest1 MODIFY c VARCHAR(50) ,algorithm=inplace,lock=none; Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> ALTER TABLE test.sbtest1 MODIFY c VARCHAR(63) ,algorithm=inplace,lock=none; Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> show create table test.sbtest1; +---------+-------------------------+ | Table | Create Table | +---------+-------------------------+ | sbtest1 | CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` varchar(63) COLLATE utf8mb4_bin DEFAULT NULL, `pad` varchar(20) COLLATE utf8mb4_bin NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin | +---------+-------------------------------------------------------------------------+ 1 row in set (0.00 sec) 本次修改顺序:VARCHAR(63)→VARCHAR(64)→VARCHAR(100),此时我们会观察到执行的 SQL 语句直接返回报错。于是我们删除 algorithm=inplace, lock=none 这两个参数,即允许本次 SQL 创建临时表以及给目标表上锁,然后重新执行 SQL,以下是相关的操作命令以及执行结果: mysql> ALTER TABLE test.sbtest1 MODIFY c VARCHAR(64) ,algorithm=inplace,lock=none; ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY. mysql> ALTER TABLE test.sbtest1 MODIFY c VARCHAR(64) ; Query OK, 1000000 rows affected (4.93 sec) Records: 1000000 Duplicates: 0 Warnings: 0 mysql> show create table test.sbtest1; +---------+--------------------------+ | Table | Create Table | +---------+--------------------------+ | sbtest1 | CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL, `pad` varchar(20) COLLATE utf8mb4_bin NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin | +---------+-------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> ALTER TABLE test.sbtest1 MODIFY c VARCHAR(100) ,algorithm=inplace,lock=none; Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 4.4 对比分析 字符长度修改 UTF8(MB3) UTF8MB4 20->50 online ddl (inplace) online ddl (inplace) 50->100 online ddl (copy) online ddl (copy) X->Y 当Y*3<256 时,inplace <br> 当X*3>=256,inplace 当 Y*4<256 时,inplace <br> 当 X*4>=256,inplace 备注 一个字符最大占用 3 个字节 一个字符最大占用 4 个字节 结论 当一个字段的最大字节长度 >=256 字符时,需要 2 个字节来表示字段长度。 使用 UTF8MB4 举例: 对于字段的最大字节长度在 256 字符内变化 (即 x*4<256 且 Y*4<256),online ddl 走 inplace 模式,效率高。 对于字段的最大字节长度在 256 字符外变化 (即 x*4>=256 且 Y*4>=256) ,online ddl 走 inplace 模式,效率高。 否则,online ddl 走 copy 模式,效率低. UTF8(MB3) 同理。 建议 为避免由于后期字段长度扩容,online ddl 走效率低的 copy 模式,建议: 对于 UTF8(MB3) 字符类型: 字符个数小于 50 个,建议设置为 VARCHAR(50) 或更小的字符长度。 字符个数接近 84(256/3=83.33)个,建议设置为varchar(84)或更大的字符长度。 对于 UTF8MB4 字符类型: 字符个数小于 50 个,建议设置为 VARCHAR(50),或更小的字符长度。 字符个数接近 64(256/4=64)个,建议设置为 VARCHAR(64) 或更大的字符长度。 本次验证结果仅供参考,若您需要在生产环境中进行操作,请结合实际情况合理定义 VARCHAR 的长度,避免造成经济损失。 更多技术文章,请访问:https://opensource.actionsky.com/ 关于 SQLE SQLE 是一款全方位的 SQL 质量管理平台,覆盖开发至生产环境的 SQL 审核和管理。支持主流的开源、商业、国产数据库,为开发和运维提供流程自动化能力,提升上线效率,提高数据质量。 SQLE 获取 类型 地址 版本库 https://github.com/actiontech/sqle 文档 https://actiontech.github.io/sqle-docs/ 发布信息 https://github.com/actiontech/sqle/releases 数据审核插件开发文档 https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse

优秀的个人博客,低调大师

私有云选型评估:OpenStack vs VMware

OpenStack和VMware都是混合云和私有云的可选项。那么问题来了,你的组织应该选择哪个呢? 不同的厂商对云计算的未来有不同的看法。比如说,亚马逊Web服务认为私有云和混合云只是通往公共云道路上的踏脚石。但是企业对围绕就业保护,安全和法规遵从方面的担忧造成了私有云,特别是混合云的部署。据行业分析机构IDC的调查,超过65%的企业IT组织在2016年以前都将致力于混合云模式。 但当涉及到混合云的实施时,事情可能并没有一些人希望的那样有条理。在混合云里,数据在公共云和私有云之间传输,WAN通信的危险性,尤其是在美国,使得这成为一个问题。 混合云实施的另一个问题是选择合适的私有云技术。许多公司使用OpenStack作为混合环境中的核心私有云软件。OpenStack构建在虚拟机管理程序之上,由一整套复杂的配置和编排云的模块组成。这是一个开源项目,业界的大部分重量级厂商,包括HP、Dell、IBM和Google,都深入参与到其中。 VMware和OpenStack整合的挑战 许多VMware的用户想知道如何使用他们目前的虚拟服务器池来创建一个可以同公有云通信的私有云。随着对VMware培训,许可和流程的大量投资,任何替代VMware的私有云的方案让一些组织望而却步。但当涉及到混合云设计,VMware的明确性又不够使得这一切变得很困难。 在VMware虚拟化服务器上运行OpenStack不是真正的问题——但我们必须小心对待我们讨论的是VMware的哪一部分。这里,我们指的是 ESXi管理程序。某些更高级别的VMware技术,包括vSphere和vCenter,有功能重叠和接口的问题,会同某些OpenStack的功能重复。 另一个集成问题是VMware vSphere控制的本地存储与OpenStack的的Swift对象存储的连接。因为它是面向块IO的,VMware和Swift不能直接等同。 私有云竞技场:OpenStack对决VMware OpenStack一开始就是云技术,而VMware最开始是作为数据中心的一个虚拟化套件。由于他们属于两个不同世代的架构,把OpenStack和VMware直接进行比较是困难的。有一些OpenStack的服务与VMware是一致的,但这个列表很短。OpenStack的项目列表中认可的30+个模块中,只有四个:计算引擎Nova、镜像管理Glance、网络模块Neutron和仪表板模块Horizon,可以直接同VMware比较。 VMware的vCloud战略使得很难比较这两种技术。vCloud与OpenStack竞争的同时,缺乏OpenStack所展示的功能范围。很多人认为,这反映了VMware对云计算企业化延迟接受的现实,并让公司处在一个追赶的位置上。 成本进一步激化了OpenStack与VMware的私有云争论。VMware ESXi虚拟机管理程序是免费的,但代码的其余部分则需要消费者支付许可费。面对服务器群在未来十年的快速扩张,许多CIO正在探索较低成本的选择 - 而该理由是推动许多组织到OpenStack的。虽然OpenStack可能引入更高的技术支持成本,这对VMware也同样适用。不过说到底,VMware通常还是比走OpenStack的路线要便宜些。 同时,一些规模较大的企业将视角放在“白盒”商品硬件上,以降低成本。对于这些组织,OpenStack可能是更好的选择,因为VMware有自己认可的硬件配置列表。 还有其他的因素起作用。 OpenStack只有5岁,仍在不断发展。其核心是稳定的,但还没有成熟到能达到VMware的质量标准。许多更新的OpenStack功能仍处于开发初期,但这就是OpenStack模块化方式的亮点。OpenStack更像是一个云“乐高”,意味着新的组件和模块会随着时间的推移被添加进来-从现在开始甚至有可能持续长达30年。 VMware vCloud也是新的东西,在许多方面都没有其他技术成熟。 VMware需要大量的功能才能赶上OpenStack。该公司与AT&T和Terremark公司合作提供混合云的能力,但一些人士认为VMware面临一个陡峭的学习曲线,因为它入市很晚。vCloud还使用内部虚拟机管理程序安装上VMware公共云的能力,这意味着一个真正开放的,与供应商无关的 VMware方案还有很长的路要走。 VMware最近推出了自己的OpenStack发布版本。VMware Integrated OpenStack,一个在vCenter和vSphere环境中支持OpenStack的软件,在三月面世。虽然确定这种方式是否有效还为时尚早,它引入了一个间接的额外层从而可能会对性能造成一定的影响。它还更复杂并且要保留那些昂贵的许可。 OpenStack正在企业,甚至在那些VMware多年 “铁杆粉丝”的组织里寻找自己的位置。许多公司已经初步尝试了OpenStack,仅仅假设VMware是更好的选择已经不再成立。 本文作者:谈翔 来源:51CTO

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册