MySQL主从之间具有不同数据类型的列的复制
2025-12-09 19:08 abce 阅读(0) 评论(0) 收藏 举报主库和从库同一表中对应列的数据类型理想情况下应相同。但只要满足特定条件,此要求并非始终要求被严格执行。通常可将特定数据类型的列复制到需具备相同类型及相同长度(适用时)或更大长度的另一列。例如:可将CHAR(10)列无障碍复制到另一CHAR(10)列,或从CHAR(10)列复制到CHAR(25)列。在特定情况下,也可实现主库某数据类型的列向目标端不同数据类型的列进行复制;当主库列的数据类型被提升为目标端相同或更大尺寸的类型时,此过程称为属性提升(attribute promotion)。
属性提升(attribute promotion)可同时应用于基于语句和基于行的复制,且不受主库或从库存储引擎类型的限制。但日志格式的选择会影响允许的数据类型转换,具体细节将在本节后文讨论。
重要提示:无论采用基于语句还是基于行的复制方式,若需启用属性提升功能,从库表的列数不得超过主库表的列数。
基于语句的复制。使用基于语句的复制时,可遵循以下简单经验法则:“若主库执行的语句在从库上也能成功执行,则该语句应能成功复制”。换言之,若语句使用的值与从库中指定列的类型兼容,则该语句可被复制。例如,任何能放入TINYINT列的值同样可插入BIGINT列;由此可推,即使将从库表中TINYINT列的类型改为BIGINT,主库对该列的成功插入操作在从库仍应成功——因为不存在合法的TINYINT值能大到超出BIGINT列的容量。
基于行的复制:属性提升与降级。行级复制支持在较小数据类型与较大类型间进行属性提升和降级。本节后文将说明如何指定是否允许降级列值进行有损(截断)或无损转换。
replica_type_conversions 控制使用基于行的复制时,从库上生效的类型转换模式。其值为由逗号分隔的零个或多个元素组成的集合,元素取自以下列表:ALL_LOSSY、ALL_NON_LOSSY、ALL_SIGNED、ALL_UNSIGNED。将此变量设为空字符串可禁止源与从库间的类型转换。该设置将立即对所有复制通道生效,包括正在运行的通道。
有损与无损转换。当目标类型无法表示要插入的值时,必须决定如何处理转换。若允许转换但截断(或修改)源值以使其“适配”目标列,则称为有损转换。无需截断或类似修改即可将源列值完整映射至目标列的转换称为无损转换。
类型转换模式
系统全局变量 replica_type_conversions 的值控制从库使用的类型转换模式。该变量取值范围如下表所示,描述了每种模式对从库类型转换行为的影响:
-- ALL_LOSSY
在此模式下,允许执行可能导致信息丢失的类型转换。
这并不意味着允许无损转换,仅表示仅允许需要有损转换或完全不转换的情况;例如,仅启用此模式时,允许将 INT 列转换为 TINYINT(有损转换),但不允许将 TINYINT 列转换为 INT 列(无损转换)。此时尝试后者转换将导致从库复制因错误停止。
--ALL_NON_LOSSY
此模式允许无需截断或对源值进行其他特殊处理的转换;即允许目标类型范围大于源类型的转换。
设置此模式不会影响是否允许有损转换。若仅设置ALL_NON_LOSSY而未设置ALL_LOSSY,则尝试可能导致数据丢失的转换(如INT转TINYINT或CHAR(25)转VARCHAR(20))将使从库停止并报错。
--ALL_LOSSY,ALL_NON_LOSSY
启用此模式时,允许所有被支持的类型转换,无论是否涉及数据丢失。
--ALL_SIGNED
将被提升的整数类型视为带符号值(默认行为)。
--ALL_UNSIGNED
将被提升的整数类型视为无符号值。
--ALL_SIGNED,ALL_UNSIGNED
尽可能将被提升的整数类型视为有符号值,否则视为无符号值。
--[]
当未设置replica_type_conversions时,不允许任何属性提升或降级;这意味着源表和目标表的所有列必须具有相同类型。
此模式为默认设置。
当整数类型被提升时,其符号性不会被保留。默认情况下,从库将所有此类值视为带符号值。可通过ALL_SIGNED、ALL_UNSIGNED或两者同时使用来控制此行为。ALL_SIGNED指示从库将所有提升的整数类型视为带符号类型;ALL_UNSIGNED则指示其视为无符号类型。同时指定两者时,从库将在可能情况下将值视为有符号,否则视为无符号;参数顺序无关紧要。
更改类型转换模式需通过新 replica_type_conversions 设置重启从库。
支持的转换类型
以下展示了不同但相似的数据类型之间支持的转换:
1.在 TINYINT、SMALLINT、MEDIUMINT、INT 和 BIGINT 整数类型之间进行转换
包括这些类型的有符号与无符号版本之间的转换。
有损转换通过将源值截断至目标列允许的最大(或最小)值实现。为确保从无符号类型转换为有符号类型时无损,目标列必须足够大以容纳源列的值域。例如,可将 TINYINT UNSIGNED 无损降级为 SMALLINT,但不能降级为 TINYINT。
2.在十进制类型 DECIMAL、FLOAT、DOUBLE 和 NUMERIC 之间进行转换时
FLOAT 转 DOUBLE 为无损转换;DOUBLE 转 FLOAT 只能进行有损转换。DECIMAL(M,D) 转换为 DECIMAL(M',D') 时,若 D' >= D 且 (M'-D') >= (M-D),则为无损转换;若出现 M' < M、D' < D 或两者同时成立的情况,则只能进行有损转换。
对于任何十进制类型,若待存储值超出目标类型容量,则按文档中定义的服务器舍入规则向下舍入。
3.字符串类型CHAR、VARCHAR与TEXT之间的转换(含不同宽度类型间的转换)均不产生数据丢失
将CHAR、VARCHAR或TEXT转换为相同或更大尺寸的同类型列时,转换永不丢失数据。若需进行有损转换,则仅在从库中插入字符串的前N个字符,其中N为目标列的宽度。
重要提示:不同字符集之间的列复制不受支持。
4.在任何字符串类型(CHAR、VARCHAR 和 TEXT)之间进行转换时,包括不同宽度之间的转换
支持 BINARY、VARBINARY 和 BLOB 任意二进制数据类型间的转换,包括不同宽度间的转换。
将 BINARY、VARBINARY 或 BLOB 转换为相同或更大尺寸的 BINARY、VARBINARY 或 BLOB 列时,数据绝不会丢失。若需进行有损转换,则仅在从库中插入字符串的前 N 个字节,其中 N 为目标列的宽度。
5.任意两个BIT列之间,无论其大小如何
当将BIT(M)列的值插入到BIT(M')列(其中M' > M)时,BIT(M')列的高位将被清零,而BIT(M)值的M位将作为BIT(M')列的低位进行设置。
当从源BIT(M)列向目标BIT(M')列插入值时,若M' < M,则为目标列赋予BIT(M')列的最大可能值。
未在上述列表中的类型之间不允许进行转换。

本文来自博客园,作者:abce,转载请注明原文链接:https://www.cnblogs.com/abclife/p/19206881
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/995404.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!